Os serviços permanecem em estado de falha após serem interrompidos com systemctl

19

nós temos um script systemd simples para iniciar um servidor MineCraft de uma maneira de serviço. O SO é o CentOS 7. Aqui está o script:

[Unit]
Description=Minecraft Server
After=syslog.target network.target

[Service]
Type=simple
WorkingDirectory=/root/Minecraft
ExecStart=/bin/java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui
Restart=on-failure

[Install]
WantedBy=multi-user.target

Iniciar o serviço funciona bem, mas ao parar, o serviço permanece em um estado com falha. Vejo:

systemctl status minecraftd.service
minecraftd.service - Minecraft Server
   Loaded: loaded (/usr/lib/systemd/system/minecraftd.service; disabled)
   Active: active (running) since Mon 2015-06-01 16:00:12 UTC; 18s ago
 Main PID: 20975 (java)
   CGroup: /system.slice/minecraftd.service
           └─20975 /bin/java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui
systemctl stop minecraftd.service
systemctl status minecraftd.service
minecraftd.service - Minecraft Server
   Loaded: loaded (/usr/lib/systemd/system/minecraftd.service; disabled)
   Active: failed (Result: exit-code) since Mon 2015-06-01 16:01:37 UTC; 3s ago
  Process: 20975 ExecStart=/bin/java -Xmx1024M -Xms1024M -jar minecraft_server.jar nogui (code=exited, status=143)
 Main PID: 20975 (code=exited, status=143)

Qualquer ideia?

obrigado

Kalise
fonte

Respostas:

27

O código de saída 143 significa que o programa recebeu um sinal SIGTERM para instruí-lo a sair, mas não tratou o sinal corretamente. Isso ocorre quase sempre devido a erros de programação e é bastante comum em aplicativos Java de todos os tipos.

Você deve poder suprimir isso adicionando o código de saída ao arquivo da unidade como um status de saída "com êxito":

[Service]
SuccessExitStatus=143
Michael Hampton
fonte
Funciona. Agora o serviço está no status inativo, conforme o esperado.
kalise
4
Qual seria a maneira "adequada" de manipular o sinal com um aplicativo Java? O mais próximo que posso encontrar seria ganchos de desligamento, mas em nenhum lugar da documentação ele menciona que os ganchos de desligamento alteram o código de saída do aplicativo.
precisa saber é
@SPoage stackoverflow.com/q/2975248/1068283 Mas, ao que parece, o Java sempre sai com o código 143 nesse caso, mesmo se houver um gancho de desligamento.
Michael Hampton
10

Para complementar a resposta de Michael, o código de saída 143 é normal aqui, é o modo como a VM Java recebe um sinal SIGTERM, enviado pelo systemd para interromper o processo. O sinal SIGTERM possui um valor numérico de 15 (consulte man signal).

Agora, de acordo com a especificação Posix, "O status de saída de um comando que terminou porque recebeu um sinal deve ser relatado como superior a 128". ( http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_08_02 )

Aqui a Java VM adiciona 128 + 15 e você obtém esse código de saída 143.

Esse código de saída diferente de zero aqui faz sentido, pois permite ver que o seu programa java saiu por causa de um sinal externo e você tem a chance de descobrir qual sinal.

Manu
fonte
O texto de especificação do POSIX referenciado parece estar especificando como um shell deve se comportar e diz "O shell é um interpretador de linguagem de comando". Uma VM Java não parece ser algo coberto por essa especificação. Como um shell interpreta uma Java VM (ou qualquer outro programa) finalizando devido ao SIGTERM - que deve definir o código de saída para 143 - certamente é coberto pela especificação, mas tenho certeza de que não há um shell envolvido aqui.
Doshea
Você está certo quanto ao fato de que essa especificação POSIX é direcionada ao shell UNIX, mas aqui parece que os autores da JVM decidiram implementar seu código de retorno da mesma maneira.
Manu