Rhel 7: o systemd falha ao iniciar um processo se a opção de segundo plano for fornecida

Rhel 7: o systemd falha ao iniciar um processo se a opção de segundo plano for fornecida

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 .serviceunidade pode ter apenas um processo daemon “principal” e a Type=opção informa ao systemd como esse processo funciona.

Type=simpleindica 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 execassim:

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=forkingindica 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=forkingtem 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=simplesem nenhuma opção de plano de fundo.

informação relacionada