Як з’ясувати, чому моя система 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 = не вдалося", я не бачу помилок ...

[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.
Andy Forceno
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.