configure o daemon java com o systemd

8

Estou usando essa definição para um trabalho systemd :

 [Unit]
 Description=Some job

 [Service]
 ExecStart=/usr/local/sbin/somejob
 User=dlt
 Type=forking

 [Install]
 WantedBy=multi-user.target

O script é chamado como segue (chamando uma rotina simples que escuta em um soquete tcpip e acrescenta a entrada a um arquivo):

 #!/bin/sh

 cd /home/user/tmp/testout
 nohup java -jar /home/user/programming/tests/java/core/SocketTest/SocketTest.jar </dev/null >/dev/null &

Depois de systemctl start somejob process ser exibido, com init como pai:

 user@CANTANDO ~$ ps -u dlt eo pid,ppid,command
   PID  PPID COMMAND
  8718     1 java -jar /home/user/programming/tests/java/core/SocketTest/SocketTest.jar

Depois de executar systemctl stop somejob , o processo não aparece mais (e a porta está fechada).

Então tudo parece bem e elegante

A minha pergunta é: esta é uma solução aceitável para executar um daemon java com systemd , ou existem ressalvas e, portanto, outras formas mais estáveis ou seguras de conseguir isso?

    
por lash 01.11.2016 / 16:07

1 resposta

11

Veja algumas pequenas modificações:

  1. Como ele escuta em um soquete de rede, torne-o uma dependência de network.target .
  2. nohup não é necessário, pois systemd irá daemonizar o executável para você.
  3. Eu acho que um script de shell separado seria um exagero, então apenas mescle-o no arquivo de serviço.
  4. Redirecionamento ( < /dev/null e assim por diante) não é necessário, pois o systemd configura um contexto de E / S padrão apropriado. De fato, se você tomar o redirecionamento out , o systemd registrará qualquer coisa enviada para a saída padrão pelo programa Java em seu diário, sem necessidade de nenhum mecanismo de log especial.
  5. A execução assíncrona do shell de chamada ( & ) não é necessária ou apropriada.
  6. Existe um padrão de comportamento específico requerido por Type=forking , e se não for seguido pelo daemon, as coisas dão errado. Então, tente Type=simple (ou Type=notify ).

O arquivo de serviço é assim:

[Unit]
Description=Some job
After=network.target

[Service]
WorkingDirectory=/home/user/tmp/testout
SyslogIdentifier=SocketTest
ExecStart=/bin/sh -c "exec java -jar /home/user/programming/tests/java/core/SocketTest/SocketTest.jar"
User=dlt
Type=simple

[Install]
WantedBy=multi-user.target

Notas:

  1. Você não pode usar apenas java como o nome do programa a ser executado. O systemd não pesquisa PATH para executáveis, e o nome do executável dado a ExecStart deve ser absoluto. Então, se você quiser uma busca de caminho, você precisa invocar através de um shell ou /usr/bin/env . Nós escolhemos /bin/sh aqui.
  2. Como isso é Type=simple , o shell deve exec Java, não executá-lo como um processo filho. O systemd controla o serviço através do processo principal e precisa ser Java, não um processo de shell pai.
  3. Como isso não está chamando diretamente o executável Java, o systemd colocará o nome sh em seu diário como o nome do serviço. Consulte Como evitar que o / usr / bin / env seja marcado nos logs do systemd como o executável para saber mais sobre isso.

Até onde eu sei, não há nenhuma advertência especial de executar o aplicativo Java com o Systemd.

    
por 01.11.2016 / 16:37