Як переконатися, що програма продовжує працювати на Linux


83

Я намагаюся забезпечити, щоб сценарій продовжував працювати на сервері розробки. Він порівнює статистику та надає веб-сервіс, тому він повинен зберігатися, але кілька разів на день він відмирає з невідомих причин. Коли ми помічаємо, ми просто запускаємо його знову, але це боляче ззаду, і деякі користувачі не мають дозволу (або ноу-хау) запускати його.

Програміст в мені хоче витратити кілька годин, щоб дійти до суті проблеми, але зайнята людина в мені вважає, що повинен бути простий спосіб виявити, якщо програма не працює, і запустити її знову.

Я знаю, що міг би cron-script ps через grep:

ps -A | grep appname

Але знову ж таки, це ще одна година мого життя, витрачена на те, щоб робити щось, що вже повинно існувати ... Чи не існує заздалегідь створеного додатка, який я можу передати виконуваний файл (необов’язково з аргументами) і який буде тримати процес необмежено довго?

У випадку, якщо це має якесь значення, це Ubuntu.


1
Це залежить від того, чи втрачається статистика, коли сценарій не запущений, але я думаю, що програміст у вас правий - вам слід дізнатись більше про те, чому сценарій не триває безкінечно.
Джонатан Леффлер

1
Це скоріше послуга на замовлення, ніж щось, що постійно зминає цифри. Якщо він виходить з ладу перед збереженням даних, нічого не втрачається; він просто виконає роботу наступного разу, коли буде виконуватися.
Олі


Питання було дано відповіді на стандартний або кращий спосіб зберегти живий процес , розпочатий init.d . Рішення включають використання systemd та /etc/inittab.
koppor

Відповіді:


37

Примітка: Upstart перебуває в режимі обслуговування і відмовився від Ubuntu, який використовує systemd. Слід ознайомитися з посібником systemd для детальної інформації про те, як написати визначення послуги.

Оскільки ви використовуєте Ubuntu, вас може зацікавити Upstart , який замінив традиційний inys sysV . Однією з ключових особливостей є те, що він може перезапустити послугу, якщо вона несподівано загине. Fedora перейшла на випускну версію, і Debian перебуває в експериментальній програмі, тому, можливо, варто розглянути її.

Однак у цій ситуації це може бути надмірним, оскільки для реалізації сценарію cron потрібно 2 хвилини.

#!/bin/bash
if [[ ! `pidof -s yourapp` ]]; then
    invoke-rc.d yourapp start
fi

Потрібно зазначити, що налаштування апстарта для управління вашою службою та її постійного запуску досить просте (ви пишете невеликий конфігураційний файл). Це рішення є набагато чистішим, простішим та кращим, ніж будь-який інший "простий" моніторинг на основі сценаріїв cron / shell.
тор

@thor - (зауважте, це з 2008 року, коли вискочка була новою, і документацію було важче отримати). Я згоден, "простий" скрипт cron мав лише показати, що сценарій також не повинен бути складним для виконання роботи.
JimB

Розумію. Я upvoted своєї відповіді в будь-якому випадку, розміщуючи свій коментар
Thor

85

Я використав простий скрипт із cron, щоб переконатися, що програма запущена. Якщо це не так, тоді він запустить його. Це може бути не ідеальним рішенням, яке ви шукаєте, але воно просте і працює досить добре.

#!/bin/bash
#make-run.sh
#make sure a process is always running.

export DISPLAY=:0 #needed if you are running a simple gui app.

process=YourProcessName
makerun="/usr/bin/program"

if ps ax | grep -v grep | grep $process > /dev/null
then
    exit
else
    $makerun &
fi

exit

Потім додайте завдання cron щохвилини або кожні 5 хвилин.


2
Це геній. Він переживе перезавантаження, і нічого не встановлювати.
Ian Purton

Я сам використовував це, оскільки для встановлення не потрібно привілей root.
JohnMudd

Що було process nameб, якщо я хочу продовжувати працювати сценарій Python?
Користувач

@User Використовуйте ps ax | grep XXXдля перерахування лише вашого процесу, тоді XXX буде ним.
strongwillow

11
Як * * * * * ps aux|grep -v grep|grep -q YourProcessName || /usr/bin/program &
однокласник

43

Моніт для цього ідеально підходить :)

Ви можете писати прості конфігураційні файли, які вказують monit спостерігати, наприклад, TCP-порт, PID-файл тощо

monit буде запускати команду, яку ви вкажете, коли процес, який він контролює, недоступний / використовує занадто багато пам'яті / занадто довго прив'язує процесор / і т.д. Також з’явиться сповіщення електронною поштою про те, що сталося, і чи може воно щось з цим зробити.

Ми використовуємо його, щоб підтримувати роботу наших веб-сайтів, одночасно попереджаючи нас, коли щось йде не так.

- Твій вірний співробітник, Моніт


19
Як ти продовжуєш працювати Моніт?
JohnMudd

2
Це досить важко навчитися. Я просто хочу перезапустити сценарій (замість служби), і я читав його документ годинами, але не міг цього зрозуміти.
Тайлер Лонг,

21

Якщо ви використовуєте дистрибутив на основі systemd, такий як Fedora та останні випуски Ubuntu, ви можете скористатися можливістю перезапуску systemd для служб. Його можна налаштувати як системну службу або як службу користувача, якщо нею потрібно керувати та запускати як конкретний користувач, що, швидше за все, має місце в конкретній ситуації OP.

Функція Перезапуск займає один з no , on-success, on-failure, on-abnormal, on-watchdog, on-abort, абоalways .

Щоб запустити його як користувач, просто помістіть такий файл як ~/.config/systemd/user/something.service:

[Unit]
Description=Something

[Service]
ExecStart=/path/to/something
Restart=on-failure

[Install]
WantedBy=graphical.target

тоді:

systemctl --user daemon-reload
systemctl --user [status|start|stop|restart] something

Не потрібні кореневі привілеї / модифікація системних файлів, не потрібні завдання cron, не потрібно нічого встановлювати, гнучкий, як пекло (див. Усі відповідні параметри служби в документації).

Дивіться також https://wiki.archlinux.org/index.php/Systemd/User для отримання додаткової інформації про використання екземпляра systemd для кожного користувача.


Чудова відповідь, але ~ / .config / systemd / user / something.service була для мене трохи неоднозначною. Частина "користувач" дослівно "користувач" чи як "ваше ім'я користувача"? Якщо це "ваше ім'я користувача", це здається мені зайвим, оскільки ви робите цей файл у своєму домашньому каталозі. Редагувати: схоже, це буквально "користувач"
Fivedogit

8

Я використав із cron "killall -0 назва програми || /etc/init.d/programname start". kill буде помилкою, якщо процес не існує. Якщо він існує, він подасть нульовий сигнал процесу (який ядро ​​буде ігнорувати і не турбувати передачу.)

Цю ідіому легко запам’ятати (ІМХО). Як правило, я використовую це, поки все ще намагаюся з’ясувати, чому не працює сама служба. Програма IMHO не повинна просто несподівано зникнути :)


7

Помістіть свій цикл у цикл - отже, коли він вийде, він запускається знову ... while (true) {запусти мою програму ..}


4
Якщо сценарій вмирає з невідомих причин, швидше за все, він також скасує сценарій циклу, ні?
Гарет,

4
Я з Garath, якби його система вбивала тривалі процеси, то запропонований цикл - який би розпочався до програми - був би знищений першим.
ekerner

2
Щоб відповісти на ваші два коментарі: Ні, якщо сценарій вмирає з невідомих причин, то сценарій циклу не впливає, оскільки він запускається в окремому процесі, але так, якщо система випадково вбиває тривалі процеси, це все одно буде проблемою - проте я сумніваюся, що це так. Решта системи не повідомляється як постраждала, і вона наповнена іншими тривалими процесами, які також були б перезапущені (лише згадано, що цей сценарій має проблему).
Klathzazt

4

З якихось причин я не зміг змусити рішення Кріса Вендта працювати, і його було важко налагодити. Цей майже такий самий, але легший для налагодження, виключає bash із зіставлення шаблонів. Для налагодження просто запустіть: bash ./root/makerun-mysql.sh. У наступному прикладі з mysql-сервером просто замініть значення змінних для processі makerunдля вашого процесу.

  • Створіть BASH-скрипт, подібний до цього ( nano /root/makerun-mysql.sh):
#!/bin/bash
process="mysql"
makerun="/etc/init.d/mysql restart"
if ps ax | grep -v grep | grep -v bash | grep --quiet $process
then
    printf "Process '%s' is running.\n" "$process"
    exit
else
    printf "Starting process '%s' with command '%s'.\n" "$process" "$makerun"
    $makerun
fi
exit
  • Переконайтеся, що його можна виконати, додавши належні дозволи для файлів (тобто chmod 700 /root/makerun-mysql.sh)

  • Потім додайте це у свій crontab ( crontab -e):

# Keep processes running every 5 minutes
*/5 * * * * bash /root/makerun-mysql.sh

1
Зверніть увагу, порівняно з рішенням Кріса Вендта, сценарій тут не запущений як фонове завдання.
Мейсон,

2

superviseІнструмент від daemontoolsб моє перевагу - але тоді все пише Ден J Bernstein мої уподобання :)

http://cr.yp.to/daemontools/supervise.html

Вам потрібно створити певну структуру каталогів для сценарію запуску програми, але вона дуже проста у використанні.


1

перш за все, як запустити цю програму? Він розгалужується на задній план? Це почалося з nohup .. & etc? Якщо це останнє, перевірте, чому воно загинуло в nohup.out, якщо це перше, побудуйте журналювання.

Що стосується вашого головного питання: ви можете це зробити, або запустити інший процес у фоновому режимі (не найкращий вибір) і використовувати pidof у bashscript, досить просто:

if [ `pidof -s app` -eq 0 ]; then
    nohup app &
fi

1

Ви можете зробити це послугою, запущеною з inittab (хоча деякі Linux перейшли на щось нове у /etc/event.d). Ці вбудовані системи гарантують, що ваш сервіс продовжує працювати, не писаючи власні сценарії та не встановлюючи щось нове.


1

Це робота для DMD (демон для моніторингу демонів). є кілька навколо; але я зазвичай просто пишу сценарій, який перевіряє, чи запущений демон, і запускаю, якщо ні, і поміщаю його в cron для запуску щохвилини.



1

Приємний, простий спосіб зробити це наступним чином:

  1. Напишіть свій сервер, щоб він помер, якщо він не може слухати очікуваний порт
  2. Встановіть cronjob, щоб намагатися запускати ваш сервер щохвилини

Якщо він не запущений, він почнеться, а якщо працює, то не буде. У будь-якому випадку ваш сервер завжди буде працювати.


0

Я думаю, що кращим рішенням є тестування функції. Наприклад, якщо вам довелося протестувати apache, недостатньо лише тестувати, чи існують процеси "apache" в системах.

Якщо ви хочете перевірити, чи є апаш OK, спробуйте завантажити просту веб-сторінку та перевірити, чи є ваш унікальний код на виході.

Якщо ні, вбийте apache -9, а потім перезапустіть. І надішліть пошту до кореневої особи (яка є переадресованою поштовою адресою до коренів компанії / сервера / проекту).


1
Це правда. Багато рішень з моніторингу, запропонованих в інших відповідях, забезпечують моніторинг протоколів.
Олі

0

Це ще простіше:

#!/bin/bash

export DISPLAY=:0

process=processname
makerun="/usr/bin/processname"

if ! pgrep $process > /dev/null
then
    $makerun &
fi

Ви повинні пам’ятати, щоб переконатися, що ім’я процесу є унікальним.

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