configurar java daemon con systemd

11

Estoy usando esta definición para un systemdtrabajo:

 [Unit]
 Description=Some job

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

 [Install]
 WantedBy=multi-user.target

El script que se llama es el siguiente (llama a una rutina simple que escucha en un socket tcpip y agrega la entrada a un archivo):

 #!/bin/sh

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

Después del systemctl start somejobproceso se muestra como en ejecución, con initsu padre:

 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

Después de realizar systemctl stop somejobel proceso ya no se muestra (y el puerto está cerrado).

Entonces todo parece bien y elegante

Mi pregunta es: ¿Es esta una solución aceptable para ejecutar un demonio java con systemd, o hay advertencias, y por lo tanto otras formas más estables o seguras de lograr esto?

latigazo
fuente

Respuestas:

14

Aquí hay algunas modificaciones menores:

  1. Como escucha en un socket de red, conviértalo en una dependencia de network.target.
  2. nohupno es necesario ya systemdque demonizará el ejecutable para usted.
  3. Creo que un script de shell separado sería una exageración, así que solo combínalo en el archivo de servicio.
  4. La redirección ( < /dev/nully así sucesivamente) no es necesaria ya que systemd configura un contexto de E / S estándar apropiado. De hecho, si saca la redirección , systemd registrará todo lo enviado a la salida estándar por el programa Java en su diario, sin que se requiera un mecanismo de registro especial.
  5. Ejecutar de forma asincrónica desde el shell de invocación ( &) no es necesario ni apropiado.
  6. Hay un patrón de comportamiento específico requerido por Type=forking, y si no es seguido por el demonio, las cosas van mal. Así que intente con Type=simple(o Type=notify).

Entonces el archivo de servicio se ve así:

[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. No puede simplemente usarlo javacomo el nombre del programa para ejecutar. systemd no busca PATHejecutables, y el nombre del ejecutable dado ExecStartdebe ser absoluto. Entonces, si desea buscar rutas, debe invocar a través de un shell o /usr/bin/env. Elegimos /bin/shaquí.
  2. Debido a que este es Type=simpleel shell debe execJava, no ejecutarlo como un proceso secundario. systemd controla el servicio a través del proceso principal, y ese debe ser Java, no un proceso de shell principal.
  3. Como esto no está invocando el ejecutable de Java directamente, systemd pondrá el nombre shen su diario como el nombre del servicio. Consulte Cómo evitar que / usr / bin / env se marque en los registros de systemd como el ejecutable para obtener más información al respecto.

Hasta donde sé, no hay una advertencia especial de ejecutar aplicaciones Java con Systemd.

Yun-Chih Chen
fuente
1
Eso no funcionará. Problema 1: este no es el shell; No hay operadores de redireccionamiento. Realmente no quieres esa redirección de todos modos. Problema 2: ExecStart exige nombres de ruta absolutos. Problema 3: unix.stackexchange.com/questions/229523
JdeBP
Buena cabeza arriba. Solo puedo arreglar el problema 1. ¿Cómo solucionas el problema 2,3?
Yun-Chih Chen el
1
Ver la respuesta como editada.
JdeBP
No creo que la mierda sea necesaria aquí.
faho
Hola @ Yun-ChihChen, ¿cómo se detiene el proceso? ¿Cómo se vería ExecStrop? He estado usando init.d junto con un archivo pid pero lo encontré más fácil. Así que necesitaba asegurarme de saber cómo parar, etc. Gracias
sensei negro