
Tengo un archivo de unidad systemd (serv_unit.service):
[Unit]
Description=My service
[Service]
Type=simple
Restart=always
RestartSec=60
StartLimitInterval=400
StartLimitBurst=3
ExecStart=/etc/init.d/myscript start
[Install]
WantedBy=multi-user.target
/etc/init.d/myscript
source /etc/myfile.sh # JAVA_home & other vars are resolved through this file
mode=$1
case "$mode" in
'start')
# Start daemon
daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args &
El problema al que me enfrento es cuando ejecuto el siguiente comando:
systemctl start serv_unit.service
No veo el proceso de Java. Pero cuando elimino el final&es decir:
daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args
se puede ver el proceso de Java (y ese proceso de Java no falla, por lo que descarta la posibilidad de que falle en segundo plano)
¿Cual es la causa?
Respuesta1
Aparte de la pregunta principal, llamar a los scripts init.d desde systemd es un poco redundante y, en general, es una mala idea para empezar. Esto es todo lo que debes necesitar:
User=abc
EnvironmentFile=/etc/myfile.conf
ExecStart=/usr/bin/env $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args
EnvironmentFile solo puede ser asignaciones KEY=value simples, pero si la configuración debe venir en sintaxis de script de shell, también puede usar:
User=abc
ExecStart=/bin/sh -c ". /etc/myfile.sh && exec $$JAVA_HOME/bin/java -cp $$appClassPath $$MAIN_CLASS $$args"
(También debe configurar SyslogIdentifier=
en ambos casos, si el servicio genera mensajes de salida estándar).
Tipos de servicio
Se espera que los servicios Systemd sigan reglas específicas. Una .service
unidad sólo puede tener un proceso demonio "principal", y la Type=
opción le dice a systemd cómo funciona ese proceso.
Type=simple
indica que el proceso inicial (es decir, lo que se inicia desde ExecStart=) en sí es el proceso principal del servicio. Tan pronto como sale el proceso principal, se considera que el servicio hainterrumpido, para que se limpien los restos.
Esto significa que si estás usando Type=simple, le estás diciendo a systemd que el demoniono lo haráentrar en 'segundo plano'. De hecho, también le estás diciendo a systemd queel script init.d– no daemon
– es el proceso principal del servicio...
Por lo tanto, sería mejor si el script init.d no solo no intentara poner el demonio real en segundo plano, sino que también lo iniciara de exec
esta manera:
case "$mode" in
'start-foreground')
# Start daemon in foreground
exec daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args
Por otro lado,Type=forking
indica que el proceso inicialvoluntadbifurcar y salir durante el procedimiento de inicio, y que el proceso principal debe descubrirse desde PIDFile= o heurísticamente.
cual usar
Con demonios que tienenincorporadoEl modo 'daemonize' Type=forking
tiene una ventaja significativa: el servicio systemd permanece en estado 'Iniciando' hasta que el demonio finalmente intenta pasar a segundo plano, momento en el cual finalmente pasa al estado 'Iniciado/Activo'. Esto ayuda a la hora de configurar dependencias, por ejemplo, el servicio A puede declarar "After=B.service".
Pero si la puesta en segundo plano se realiza por medios externos, como la &
función de shell, sin nada que informe si el demonio está listo o no todavía, entonces es completamente inútil.inútily probablemente deberías usarlo Type=simple
sin ninguna opción de fondo.