Назад | Перейти на главную страницу

Служба Node.JS systemd не перезапускается

У меня есть простой сервисный модуль systemd для запуска моего веб-сервера Node.JS, и по какой-то причине Restart=on-failure не работает и перезапускает процесс.

Вот мой файл служебной единицы (с удаленными собственными именами):

[Unit]
Description=Node.JS web server
After=network.target

[Service]
User=villa
Environment=NODE_PATH=.
WorkingDirectory=/path/to/server/code
PermissionsStartOnly=true
ExecStart=/usr/local/bin/node server.js
ExecStop=/bin/killall node
Restart=on-failure
RestartSec=1

[Install]
WantedBy=multi-user.target

Затем я делаю daemon-reload, затем restart процесс, и убить его SIGKILL вот так:

[root@localhost ~]# ps -ef | grep node
villa    24783     1 17 10:54 ?        00:00:00 /usr/local/bin/node server.js
root     25172 26051  0 10:54 pts/1    00:00:00 grep --color=auto node
[root@localhost ~]# kill -9 24783
[root@localhost ~]# sleep 2
[root@localhost ~]# ps -ef | grep node
root     29462 26051  0 10:55 pts/1    00:00:00 grep --color=auto node

Как видите, даже дождавшись дольше чем RestartSec настройки, процесс не запускается.

Это то, что находится в статусе после завершения процесса, как указано выше:

[root@localhost ~]# systemctl -l status webserver.service
● webserver.service - Node.JS web server
   Loaded: loaded (/etc/systemd/system/webserver.service; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Wed 2017-05-03 10:54:53 EDT; 7min ago
  Process: 27843 ExecStop=/bin/killall node (code=exited, status=1/FAILURE)
  Process: 24783 ExecStart=/usr/local/bin/node server.js (code=killed, signal=KILL)
 Main PID: 24783 (code=killed, signal=KILL)

May 03 10:54:31 localhost.localdomain node[24783]: <...web server's standard output, nothing abnormal at all...>
May 03 10:54:53 localhost.localdomain systemd[1]: webserver.service: main process exited, code=killed, status=9/KILL
May 03 10:54:53 localhost.localdomain systemd[1]: webserver.service: control process exited, code=exited status=1
May 03 10:54:53 localhost.localdomain systemd[1]: Unit webserver.service entered failed state.
May 03 10:54:53 localhost.localdomain systemd[1]: webserver.service failed.

Странно то, что если я использую тот же самый файл служебной единицы, но с командой /usr/bin/sleep 1000 вместо того node server.js, то sleep процесс перезапускается правильно и сразу после моего kill -9. Так что с Node.JS должно быть что-то странное.

Есть идеи, почему мой Node-процесс не запускается?

Оказалось, что мой файл служебной единицы systemd все время был правильным (за вычетом удаления ExecStop= линия, которая Отметить как опубликованное, что сделало мой файл Больше верный). Моя проблема заключалась в том, что файл моей службы находился в /usr/lib/systemd/system, и, к сожалению, другой разработчик разместил тот же файл - без Restart= линия - в /etc/systemd/system, не сказав мне.

В соответствии с systemd.unit(5) (man systemd.unit):

Файлы модулей загружаются из набора путей, определенных во время компиляции, описанных в двух таблицах ниже. Файлы модулей, найденные в каталогах, перечисленных ранее, переопределяют файлы с тем же именем в каталогах ниже в списке.

   Table 1.  Load path when running in system mode (--system).
   ┌────────────────────────┬─────────────────────────────┐
   │Path                    │ Description                 │
   ├────────────────────────┼─────────────────────────────┤
   │/etc/systemd/system     │ Local configuration         │
   ├────────────────────────┼─────────────────────────────┤
   │/run/systemd/system     │ Runtime units               │
   ├────────────────────────┼─────────────────────────────┤
   │/usr/lib/systemd/system │ Units of installed packages │
   └────────────────────────┴─────────────────────────────┘

Короче говоря, systemd видел файл в /etc/systemd/system у которого не было Restart= линия в нем перед он видел мой обновленный файл в /usr/lib/systemd/system который имел Restart= линия. Мне просто пришлось удалить устаревший файл, и моя проблема была решена.

Как я читаю логи, он может умирать из-за ExecStop=/bin/killall node, который отображается как закрывающийся со статусом «1 / FAILURE».

Кажется это killall команда запускается как root из-за PermissionsStartOnly=true. Команда ExecStop также кажется опасной и ненужной. Это опасно, потому что может убить процессы узла, не связанные с этим модулем. Запуск от имени пользователя root может иметь непредвиденные последствия.

это также не нужно, потому что systemd остановит ваше приложение Node для вас. По умолчанию он сначала отправит процессу SIGTERM. Затем, если он не ответит на это, позже будет выдан SIGKILL.

Попробуйте удалить свой ExecStop= линия.