
Estoy usando esta definición para un systemd
trabajo:
[Unit]
Description=Some job
[Service]
ExecStart=/usr/local/sbin/somejob
User=dlt
Type=forking
[Install]
WantedBy=multi-user.target
El script se llama de la siguiente manera (llamando 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 de que systemctl start somejob
el proceso se muestre como en ejecución, con init
como 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 somejob
el proceso ya no aparece (y el puerto está cerrado).
Entonces todo parece estar bien y elegante.
Mi pregunta es: ¿Es esta unasolución aceptablepara ejecutar un demonio de Java con systemd
, ¿o hay advertencias y, por lo tanto, otras formas más estables o seguras de lograrlo?
Respuesta1
Aquí hay algunas modificaciones menores:
- Dado que escucha en un socket de red, conviértalo en una dependencia de
network.target
. nohup
no es necesario ya quesystemd
demonizará el ejecutable por usted.- Creo que un script de shell separado sería excesivo, así que simplemente combínalo en el archivo de servicio.
- La redirección (
< /dev/null
y demás) no es necesaria ya que systemd configura un contexto de E/S estándar apropiado. De hecho, si tomas la redirecciónafuerasystemd registrará todo lo que el programa Java envíe a la salida estándar en su diario, sin necesidad de ningún mecanismo de registro especial. &
No es necesario ni apropiado ejecutar de forma asincrónica desde el shell de invocación ( ).- Hay un patrón de comportamiento específico requerido por
Type=forking
, y si el demonio no lo sigue, las cosas van mal. Así que prueba conType=simple
(oType=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:
- No puede simplemente usarlo
java
como el nombre del programa a ejecutar. systemd no buscaPATH
ejecutables y el nombre del ejecutable asignadoExecStart
debe ser absoluto. Entonces, si desea buscar una ruta, debe invocarla a través de un shell o/usr/bin/env
. Elegimos/bin/sh
aquí. - Debido a que este es
Type=simple
el shell,exec
Java debe ejecutarlo, no 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. - Debido a que esto no invoca el ejecutable de Java directamente, systemd pondrá el nombre
sh
en su diario como nombre del servicio. VerCómo evitar que /usr/bin/env se marque en los registros de systemd como ejecutablepara más información sobre esto.
Hasta donde yo sé, no hay ninguna advertencia especial al ejecutar una aplicación Java con Systemd.