Уникайте PID-файлів, кронів чи будь-чого іншого, що намагається оцінити процеси, які не є їхніми дітьми.
Є дуже вагома причина, чому в UNIX можна ТОЛЬКО чекати своїх дітей. Будь-який метод (ps-синтаксичний аналіз, pgrep, зберігання PID, ...), який намагається обійти цю проблему і має в собі отвори. Просто скажіть ні .
Натомість вам потрібно, щоб процес, який відстежує ваш процес, був батьківським процесом. Що це означає? Це означає, що лише той процес, який розпочинає ваш процес, може надійно чекати його закінчення. У баші це абсолютно тривіально.
until myserver; do
echo "Server 'myserver' crashed with exit code $?. Respawning.." >&2
sleep 1
done
Вищезгаданий фрагмент коду bash працює myserver
в until
циклі. Перший рядок починається myserver
і чекає його закінчення. Коли він закінчується, until
перевіряє його статус виходу. Якщо статус виходу є 0
, це означає, що він закінчився витончено (це означає, що ви попросили його якось закрити, і це було успішно). У такому випадку ми не хочемо його перезавантажувати (ми просто попросили його закрити!). Якщо статус виходу немає 0
, until
запуститься тіло циклу, яке надсилає повідомлення про помилку на STDERR і через 1 секунду перезапускає цикл (назад до рядка 1) .
Чому ми чекаємо секунди? Тому що, якщо щось не в порядку із послідовністю запуску, myserver
і вона негайно виходить з ладу, у вас буде дуже інтенсивний цикл постійного перезавантаження та збоїв на руках. sleep 1
Забирає напругу від цього.
Тепер все, що вам потрібно зробити, це запустити цей скрипт bash (асинхронно, напевно), і він буде відслідковувати myserver
та перезапускати його за необхідності. Якщо ви хочете запустити монітор під час завантаження (змусивши сервер "пережити" перезавантаження), ви можете запланувати його в кроні користувача (1) за допомогою @reboot
правила. Відкрийте свої правила cron за допомогою crontab
:
crontab -e
Потім додайте правило для запуску сценарію монітора:
@reboot /usr/local/bin/myservermonitor
Альтернативно; подивіться на inittab (5) та / etc / inittab. Ви можете додати туди рядок, щоб він myserver
почався на певному рівні init і автоматично відновився.
Редагувати.
Дозвольте додати трохи інформації про те, чому не використовувати файли PID. Поки вони дуже популярні; вони також дуже хибні, і немає жодної причини, чому ви не зробили б це правильно.
Врахуйте це:
Утилізація PID (знищення неправильного процесу):
/etc/init.d/foo start
: почати foo
, записати foo
PID в/var/run/foo.pid
- Через деякий час:
foo
помирає якось.
- Трохи пізніше: будь-який випадковий процес, який починається (називаємо його
bar
), приймає випадковий PID, уявіть, що він має foo
старий PID.
- Ви помічаєте
foo
зникнення: /etc/init.d/foo/restart
читає /var/run/foo.pid
, перевіряє, чи він ще живий, знаходить bar
, думає foo
, що вбиває, заводить нове foo
.
PID-файли залишаються несвіжими. Вам потрібна занадто складна (або, я повинен сказати, нетривіальна) логіка, щоб перевірити, чи PID файл несвіжий, і будь-яка така логіка знову вразлива 1.
.
Що робити, якщо ви навіть не маєте доступу до запису або перебуваєте в середовищі лише для читання?
Це безглузда надмірність; подивіться, наскільки простий мій приклад вище. Зовсім не потрібно це ускладнювати.
Дивіться також: Чи все-таки помилки PID-файлів робляться "правильно"?
До речі; ще гірше, ніж PID-файли, розбирає ps
! Ніколи цього не роби.
ps
дуже нерепортаж. Хоча ви знаходите його майже в кожній системі UNIX; його аргументи сильно різняться, якщо потрібно нестандартний вихід. А стандартний вихід - ТІЛЬКИ для споживання людиною, а не для сценарію розбору!
- Розбір
ps
призводить до багато хибних позитивних результатів. Візьміть ps aux | grep PID
приклад, і тепер уявіть, що хтось починає процес з числом десь як аргумент, який, як і суперечить, PID, з яким ви дивились свого демона! Уявіть, що двоє людей починають X сеанс, і ви жалієтесь за X, щоб убити вашого. Це просто всі види поганого.
Якщо ви не хочете керувати процесом самостійно; є кілька ідеально хороших систем, які будуть виконувати функції монітора ваших процесів. Наприклад, погляньте на біг .