configurar o daemon java com systemd

configurar o daemon java com systemd

Estou usando esta definição para um systemdtrabalho:

 [Unit]
 Description=Some job

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

 [Install]
 WantedBy=multi-user.target

O script chamado é o seguinte (chamar uma rotina simples que escuta em um soquete tcpip e anexa 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 &

Após systemctl start somejobo processo aparecer como em execução, tendo initcomo 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

Após realizar systemctl stop somejobo processo não aparece mais (e a porta é fechada).

Então tudo parece bem e elegante

Minha pergunta é: isso é umsolução aceitávelpara executar um daemon java com systemdou há ressalvas e, portanto, outras maneiras mais estáveis ​​​​ou seguras de conseguir isso?

Responder1

Aqui estão algumas pequenas modificações:

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

Portanto, o arquivo de serviço fica 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 simplesmente usar javacomo nome do programa a ser executado. O systemd não procura PATHexecutáveis, e o nome do executável fornecido ExecStartdeve ser absoluto. Portanto, se você quiser pesquisar o caminho, precisará invocar por meio de um shell ou arquivo /usr/bin/env. Nós escolhemos /bin/shaqui.
  2. Porque este é Type=simpleo shell que deve execJava, não executá-lo como um processo filho. systemd controla o serviço por meio do processo principal, e isso precisa ser Java, não um processo shell pai.
  3. Como isso não invoca diretamente o executável Java, o systemd colocará o nome shem seu diário como o nome do serviço. VerComo evitar que /usr/bin/env seja marcado nos logs do systemd como executávelpara saber mais sobre isso.

Até onde eu sei, não há nenhuma advertência especial sobre a execução de aplicativos Java com Systemd.

informação relacionada