configurar java daemon com systemd

11

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 da seguinte maneira (chamando 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 o systemctl start somejobprocesso aparecer como em execução, com 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

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

Então, tudo parece bem e elegante

Minha pergunta é: Essa é uma solução aceitável para executar um daemon java com systemd, ou existem advertências e, portanto, outras maneiras mais estáveis ​​ou seguras de se conseguir isso?

chicote
fonte

Respostas:

14

Aqui estão algumas pequenas modificações:

  1. Como escuta em um soquete de rede, faça disso uma dependência de network.target.
  2. nohupnão é necessário, pois systemddaemonize o executável para você.
  3. Eu acho que um script de shell separado seria um exagero, então apenas o mescle 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. De fato, se você remover o redirecionamento, o systemd registrará qualquer coisa enviada à saída padrão pelo programa Java em seu diário, sem a necessidade de nenhum mecanismo especial de registro.
  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 exigido por Type=forking, e se 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 o nome do programa para executar. systemd não procura PATHpor executá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 /usr/bin/env. Nós escolhemos /bin/shaqui.
  2. Porque este é Type=simpleo shell deve execJava, não executá-lo como um processo filho. O systemd controla o serviço através do processo principal, e isso precisa ser Java, não um processo de shell pai.
  3. Como isso não está chamando o executável Java diretamente, o systemd colocará o nome shem seu diário como o nome do serviço. Consulte Como evitar que / usr / bin / env seja marcado nos logs do systemd como executável para obter mais informações.

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

Yun-Chih Chen
fonte
1
Isso não vai funcionar. Problema 1: Este não é o shell; não há operadores de redirecionamento. Você realmente não quer esse redirecionamento de qualquer maneira. Problema 2: ExecStart exige nomes de caminho absolutos. Problema 3: unix.stackexchange.com/questions/229523
JdeBP
Boa cabeça erguida. Só consigo resolver o problema 1. Como você corrige o Problema 2,3?
Yun-Chih Chen
1
Veja a resposta como editada.
JdeBP
Eu não acho que o sh seja necessário aqui.
Faho # 18/16
Olá @ Yun-ChihChen, como você para o processo. Como seria o ExecStrop? Eu tenho usado init.d junto com um arquivo pid, mas achei isso mais fácil. Então eu precisava ter certeza que eu sei como parar etc Graças
sensei preto