
Eu tenho um arquivo de unidade 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 &
O problema que estou enfrentando é quando executo o seguinte comando:
systemctl start serv_unit.service
Não vejo processo java. Mas quando eu removo o final&ou seja:
daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args
o processo java pode ser visto (e que o processo java não está travando, o que exclui a possibilidade de ele travar em segundo plano)
Qual é a causa?
Responder1
Além da questão principal, chamar scripts init.d do systemd é um pouco redundante e geralmente uma má ideia para começar. Isso é tudo que você precisa:
User=abc
EnvironmentFile=/etc/myfile.conf
ExecStart=/usr/bin/env $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args
EnvironmentFile só pode ser atribuições simples de KEY=value, mas se a configuração precisar vir na sintaxe de script de shell, você também poderá usar:
User=abc
ExecStart=/bin/sh -c ". /etc/myfile.sh && exec $$JAVA_HOME/bin/java -cp $$appClassPath $$MAIN_CLASS $$args"
(Você também deve definir SyslogIdentifier=
em ambos os casos, se o serviço produzir mensagens stdout.)
Tipos de serviço
Espera-se que os serviços Systemd sigam regras específicas. Uma .service
unidade pode ter apenas um processo daemon “principal” e a Type=
opção informa ao systemd como esse processo funciona.
Type=simple
indica que o processo inicial (ou seja, o que é iniciado em ExecStart=) é o processo principal do serviço. Assim que o processo principal termina, o serviço é considerado como tendoparou, então todas as sobras são limpas.
Isso significa que se você estiver usando Type=simple, você está dizendo ao systemd que o daemonnão vouvá para 'segundo plano'. Na verdade, você também está dizendo ao systemd queo script init.d– não daemon
– é o processo principal do serviço...
Portanto, seria melhor se o script init.d não apenas não tentasse colocar o daemon real em segundo plano, mas também o iniciasse exec
assim:
case "$mode" in
'start-foreground')
# Start daemon in foreground
exec daemon --user=abc $JAVA_HOME/bin/java -cp $appClassPath $MAIN_CLASS $args
Por outro lado,Type=forking
indica que o processo inicialvaifork e exit durante o procedimento de inicialização, e que o processo principal deve ser descoberto em PIDFile= ou heuristicamente.
Qual usar
Com daemons que têmconstruídas emO modo 'daemonize' Type=forking
tem uma vantagem significativa: o serviço systemd permanece no estado 'Iniciando' até que o daemon finalmente tente entrar em segundo plano, momento em que finalmente passa para o estado 'Iniciado/Ativo'. Isto ajuda na configuração de dependências, por exemplo, o serviço A pode declarar "After=B.service".
Mas se o background for feito por meios externos, como o &
recurso shell – sem nada que informe se o daemon está pronto ou ainda não – então é completamenteinútile você provavelmente deveria usar Type=simple
sem nenhuma opção de plano de fundo.