Como descubro por que meu serviço systemctl não foi iniciado no CentOS 7?

1

Estou usando o CentOS 7. Como descubro por que um serviço está falhando ao iniciar? Eu criei este serviço

[rails@server ~]$ sudo cat /usr/lib/systemd/system/nodejs.service
[Unit]
Description=nodejs server

[Service]
User=rails
Group=rails
ExecStart=/home/rails/NodeJSserver/start.sh
ExecStop=/home/rails/NodeJSserver/stop.sh

[Install]
WantedBy=multi-user.target

O arquivo aponta para isso

[rails@server ~]$ cat /home/rails/NodeJSserver/start.sh
#!/bin/bash

forever start /home/rails/NodeJSserver/server.js

Eu posso executar este arquivo muito bem sozinho. Mas quando tento executá-lo como parte do serviço, percebo que o servidor nodeJS não foi iniciado. Mesmo quando eu verificar "sudo systemctl - state = failed", não vejo nenhum erro ...

[rails@server ~]$ sudo systemctl enable NodeJSserver
[rails@server ~]$ sudo systemctl start NodeJSserver
[rails@server ~]$
[rails@server ~]$
[rails@server ~]$ forever list
info:    No forever processes running
[rails@server ~]$
[rails@server ~]$
[rails@server ~]$ sudo systemctl --state=failed
  UNIT                           LOAD   ACTIVE SUB    DESCRIPTION
● nginx.service                  loaded failed failed The nginx HTTP and reverse proxy server
● systemd-sysctl.service         loaded failed failed Apply Kernel Variables
● systemd-vconsole-setup.service loaded failed failed Setup Virtual Console

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

3 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

Como descubro por que meu serviço falhou ao iniciar?

    
por Dave 08.05.2018 / 17:24

1 resposta

0

Seu serviço não tem Type= especificado na seção [Service] , então systemd assume que você quis dizer Type=simple .

Isso significa que systemd esperará que o processo iniciado com ExecStart= continue em execução enquanto o serviço estiver em execução. Mas parece que o seu start.sh apenas executa um comando e depois sai. Isso é o comando forever : forever start inicia o comando de destino como um daemon, ou em outras palavras, em segundo plano. Assim que o comando forever start for concluído, o shell executando start.sh será encerrado.

Nesse momento, systemd considera este serviço como falho. Mas espere, o grupo de controle designado para esse serviço ainda tem um processo em execução nele. "Então," pensa systemd ", não apenas falhou, mas também deixou uma bagunça atrás de si. Não pode ter isso." Como não há KillMode= nem KillSignal= especificado, systemd prossegue com seus padrões e envia um SIGTERM para qualquer processo restante nesse grupo de controle, e se eles não pararem em tempo hábil, segue com um SIGKILL Depois disso, seu processo atual do NodeJS estará morto, garantido.

Como corrigir isso

Como o comando executado com ExecStart= será encerrado assim que o servidor real for iniciado, você não poderá usar o padrão Type=simple . Você deve especificar outro tipo de serviço.

Você pode usar o Type=forking . Com esse tipo, man systemd.service recomenda o uso de uma opção PIDFile= , portanto, se seu servidor NodeJS criar um arquivo PID para si mesmo (ou você adicionar opções ao comando forever para criar um para ele), você deverá deixar systemd saiba onde será.

[Service]
Type=forking
PIDFile=/absolute/path/to/nodejs.pid
User=rails
... <the rest as before>

Se Type=forking não funcionar para você, especifique Type=oneshot com RemainAfterExit=yes .

Isso faz com que systemd apenas execute o comando ExecStart= ao iniciar seu serviço e ExecStop= ao interrompê-lo e não se importe com mais nada.

systemd ainda lembrará se o serviço foi definido pela última vez em um estado parado ou iniciado. Portanto, se você configurar outro serviço para depender desse serviço e, em seguida, interromper seu serviço NodeJS manualmente, o outro serviço não será interrompido automaticamente e, sem dúvida, retornará erros quando não puder usar seu serviço NodeJS.

A terceira opção é ignorar totalmente o comando forever e deixar que systemd faça o trabalho de reiniciar o processo NodeJS. Nesse caso, toda a sua unidade nodejs.service seria:

[Unit]
Description=nodejs server

[Service]
User=rails
Group=rails
ExecStart=/home/rails/NodeJSserver/server.js
Restart=always

[Install]
WantedBy=multi-user.target

Você pode adicionar outras opções.

Por exemplo, você pode especificar RestartSec=5 para especificar um período de espera de 5 segundos antes de tentar reiniciar o serviço se ele morrer inesperadamente, para evitar sobrecarregar os recursos do sistema por tentativas frequentes de reinicialização se o serviço continuar morrendo imediatamente após ser reiniciado por algum tempo razão. (O valor padrão RestartSec= é 100 ms.)

Ou se você quiser que o serviço seja reiniciado se ele retornar alguns valores de status de saída específicos, mas considere que ele falhou em outros, também há opções para isso.

    
por 08.05.2018 / 21:19