Как выяснить, почему мой сервис systemctl не запускался в CentOS 7?

12

Я использую CentOS 7. Как мне выяснить, почему служба не запускается? Я создал этот сервис

[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

Файл указывает на это

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

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

Я могу запустить этот файл сам по себе. Но когда я пытаюсь запустить его как часть службы, я замечаю, что мой сервер nodeJS не запущен. Даже когда я проверяю "sudo systemctl --state = fail", я не вижу никаких ошибок ...

[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'.

Как выяснить, почему мой сервис не запустился?

Дейв
источник
journalctl -u nodejsдолжен дать вам более значимое сообщение об ошибке.
Федерико Клез Каллока
Я получаю сообщение «Файлы журнала не найдены».
Дейв,
sudo journalctl должен работать. Также в файле start.sh проверьте, перенаправляет ли файл журнала вывода куда-либо еще.
rogerdpack

Ответы:

13

Ваш сервис не Type=указан в [Service]разделе, поэтому systemdпредполагается, что вы имели в виду Type=simple.

Это означает, systemdчто ожидаемый процесс ExecStart=будет продолжать работать до тех пор, пока служба работает. Но похоже, что вы start.shтолько запускаете одну команду и затем выходите. То есть команда : запускает целевую команду как демон, или другими словами, в фоновом режиме. Как только команда завершится, запущенная оболочка завершится.foreverforever startforever startstart.sh

В этот момент systemdсчитается, что эта служба не работает. Но подождите, контрольная группа, назначенная для этой службы, все еще содержит запущенный процесс. «Итак, - думает systemd, - он не только потерпел неудачу, но и оставил после себя беспорядок. Не может этого иметь». Так как нет и KillMode=не KillSignal=указано, systemdпродолжает свои значения по умолчанию и отправляет SIGTERM для любых оставшихся процессов в этой контрольной группе, и если они не останавливаются своевременно, следует SIGKILL. После этого ваш фактический процесс NodeJS будет мертв, гарантировано.

Как это исправить

Поскольку команда, с которой вы работаете, ExecStart=завершится, как только будет запущен реальный сервер, вы не можете использовать значение по умолчанию Type=simple. Вы должны указать другой тип сервиса.

Вы могли бы использовать Type=forking. Для этого типа man systemd.serviceрекомендуется использовать PIDFile=параметр, поэтому, если ваш сервер NodeJS создает файл PID для себя (или вы добавляете параметры в foreverкоманду, чтобы он создавал его для него), вы должны сообщить systemd, где он будет.

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

Если у Type=forkingвас не работает, то вы можете указать Type=oneshotс RemainAfterExit=yes.

Это заставляет systemdпросто запускать ExecStart=команду при запуске службы и ExecStop=при ее остановке, и не заботиться ни о чем другом.

systemdвсе равно будет помнить, был ли последний раз установлен сервис в остановленном или запущенном состоянии. Таким образом, если вы установите другую службу в зависимости от этой службы, а затем остановите службу NodeJS вручную, другая служба не остановится автоматически и, несомненно, вернет ошибки, когда не сможет использовать вашу службу NodeJS.


Третий вариант - foreverполностью пропустить команду и позволить systemdперезапустить процесс NodeJS. В этом случае весь ваш nodejs.serviceблок будет:

[Unit]
Description=nodejs server

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

[Install]
WantedBy=multi-user.target

Вы можете добавить другие варианты.

Например, вы можете RestartSec=5указать 5-секундный спящий режим перед попыткой перезапустить службу, если она неожиданно умирает, чтобы избежать перегрузки системных ресурсов частыми попытками перезапуска, если ваша служба продолжает умирать сразу после перезапуска по какой-либо причине. (Значение по умолчанию RestartSec=составляет 100 мс.)

Или, если вы хотите, чтобы служба была перезапущена, если она возвращает какие-то определенные значения состояния выхода, но считает, что это не удалось на других, есть варианты для этого тоже.

Телком
источник
У меня был сервис, который не останавливался и не запускался должным образом (он запускается, но процесс systemctl никогда не завершается). Просто хочу добавить, что в моем случае все, что мне нужно было сделать, это добавить Restart=alwaysв мой файл конфигурации .service.
Энди Форсено