У меня есть простой сервисный модуль 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=
линия.