Уникайте 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, записати fooPID в/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, щоб убити вашого. Це просто всі види поганого.
Якщо ви не хочете керувати процесом самостійно; є кілька ідеально хороших систем, які будуть виконувати функції монітора ваших процесів. Наприклад, погляньте на біг .