У меня есть приложение узла, работающее через службу systemd в Ubuntu 16.04.
Однако через некоторое время сервис перезапускается автоматически.
Вот что я получаю в журналах:
Mar 17 14:35:10 testmachine systemd[1]: myService.service: Main process exited, code=exited, status=7/NOTRUNNING
Mar 17 14:35:10 testmachine systemd[1]: myService.service: Unit entered failed state.
Mar 17 14:35:10 testmachine systemd[1]: myService.service: Failed with result 'exit-code'.
Mar 17 14:35:40 testmachine systemd[1]: myService.service: Service hold-off time over, scheduling restart.
Насколько я понимаю, systemd обнаруживает, что служба не запущена, и перезапускается через 30 секунд, как я указал в файле конфигурации службы.
myService.service
[Unit]
Description=The will start node app
After=cleanMongo.service
[Service]
ExecStart=/media/path/to/execution/scriptFile
Restart=always
RestartSec=30
[Install]
WantedBy=multi-user.target
Но моя проблема в том, почему он думает, что служба не работает? Приложение делает свое дело и в середине перезапускается.
PS: У меня много заданий CRON, запущенных в приложении узла, это тот случай, когда процесс слишком занят, чтобы ответить на какой-то isAlive
из systemd? И поэтому systemd думает, что не работает?
Обычно systemd / systemctl сообщает об ошибке запуска (если / когда вы запустите sudo systemctl start myService.service
).
Я бы проверил:
sudo systemctl status myService.service
sudo journalctl -ln 2000 -u myService
Результат любого из них может помочь в диагностике проблемы (возможно, лучше использовать journalctl).
Также стоит попробовать воспроизвести то, что делает ваш служебный модуль systemd, то есть попытаться запустить ту же команду из интерактивного сеанса (потенциально с использованием sudo) и посмотреть, какие ошибки сообщаются.
systemd / systemctl фактически отслеживает PID, поэтому опрос не должен быть проблемой.
Обновлено в зависимости от определения вашей службы запуск сценария оболочки может быть одной из составляющих проблемы.
Ваша конфигурация systemd ожидает, что сможет отслеживать сам процесс по PID. Тем не менее, он будет «видеть» PID сценария, но, в зависимости от того, как вы запускаете узел из этого сценария, он может быть не в состоянии отслеживать PID узла.
Кажется, более надежным подходом будет запуск узла напрямую (как предлагается Вот):
[Unit]
Description=Node.js Example Server
#Requires=After=mysql.service # Requires the mysql service to run first
[Service]
ExecStart=/usr/local/bin/node /opt/nodeserver/server.js
#WorkingDirectory=/opt/nodeserver # Required on some systems
Restart=always
RestartSec=10 # Restart service after 10 seconds if node service crashes
StandardOutput=syslog # Output to syslog
StandardError=syslog # Output to syslog
SyslogIdentifier=nodejs-example
#User=<alternate user>
#Group=<alternate group>
Environment=NODE_ENV=production PORT=1337
[Install]
WantedBy=multi-user.target
Таким образом, systemd сможет отслеживать правильный PID.
Если вам нужно выполнить некоторые команды перед запуском узла, рассмотрите возможность использования systemd ExecStartPre
.
Существует ряд других опций, которые предоставляет systemd (см. единичный файл man-страницу), что может позволить вам избежать использования оболочки:
ExecStartPre
позволяет выполнять задачи до запуска основного процесса (и ExecStartPost
выполнять задачи после)Require
, Wants
, Before
, и After
, и вы также можете использовать Conflicts
или различные Condition*
ключевые слова.Во-первых, я не эксперт по nodejs.
Как говорили другие, вы должны как можно больше переместиться в модуль systemd. В cd
можно заменить на WorkingDirectory
sudo бесполезен, но его можно заменить на User
и переменная среды может быть установлена Environment
.
Systemd не ожидает вызова isAlive от вашего демона, если Type
это! = notify
(по умолчанию simple
)
В NOTRUNNING
интерпретация кода выхода вашего процесса, это означает, что процесс вашего узла завершается с кодом ошибки 7 Node Doc говорит, что код выхода означает «Произошло неперехваченное исключение, и сама функция внутреннего фатального обработчика исключений вызвала ошибку при попытке ее обработать». поэтому должен быть какой-то вывод в журнале или в месте назначения журнала nodejs.