Перезапуск Systemd = завжди не шанується


54

Примітка. Я написав статтю на Medium, в якій пояснюється, як створити службу та як уникнути цієї конкретної проблеми: Створення служби Linux із системою systemd .

Оригінальне запитання:


Я використовую systemd, щоб постійно підтримувати робочий скрипт:

[Unit]
Description=My worker
After=mysqld.service

[Service]
Type=simple
Restart=always
ExecStart=/path/to/script

[Install]
WantedBy=multi-user.target

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

Jun 14 11:10:31 localhost systemd[1]: test.service: Main process exited, code=exited, status=1/FAILURE
Jun 14 11:10:31 localhost systemd[1]: test.service: Unit entered failed state.
Jun 14 11:10:31 localhost systemd[1]: test.service: Failed with result 'exit-code'.
Jun 14 11:10:31 localhost systemd[1]: test.service: Service hold-off time over, scheduling restart.
Jun 14 11:10:31 localhost systemd[1]: test.service: Start request repeated too quickly.
Jun 14 11:10:31 localhost systemd[1]: Failed to start My worker.
Jun 14 11:10:31 localhost systemd[1]: test.service: Unit entered failed state.
Jun 14 11:10:31 localhost systemd[1]: test.service: Failed with result 'start-limit'.

Аналогічно, якщо мій сценарій працівника кілька разів не працює зі статусом виходу 255, systemdвідмовиться від спроби перезапустити його:

Jun 14 11:25:51 localhost systemd[1]: test.service: Failed with result 'exit-code'.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Service hold-off time over, scheduling restart.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Start request repeated too quickly.  
Jun 14 11:25:51 localhost systemd[1]: Failed to start My worker.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Unit entered failed state.  
Jun 14 11:25:51 localhost systemd[1]: test.service: Failed with result 'start-limit'.

Чи є спосіб , щоб змусити , systemdщоб завжди повторити через кілька секунд?

Відповіді:


53

Я хотів би трохи продовжити відповідь Рахуля.

SystemD намагається перезапустити кілька разів ( StartLimitBurst) і припиняє спроби, якщо кількість спроб буде досягнуто в межах StartLimitIntervalSec. Обидва варіанти належать до [unit]розділу.

Затримка між виконанням за замовчуванням становить 100 мс ( RestartSec), що призводить до дуже швидкого досягнення межі швидкості.

SystemD не намагатиметься більше автоматичного перезавантаження для одиниць із визначеною політикою перезапуску :

Зауважте, що одиниці, налаштовані на Restart=та які досягають ліміту початку, більше не намагаються перезапустити; однак, вони можуть бути перезапущені вручну в більш пізній момент, після чого логіка перезапуску знову активується.

Відповідь Рахуля допомагає, оскільки більша затримка заважає досягти лічильника помилок протягом StartLimitIntervalSecчасу. Правильна відповідь - це встановити RestartSecі StartLimitBurstрозумні значення, і розумні.


5
Тепер, коли я (нарешті) зрозумів, як це працює, після деяких спроб і помилок, я можу побачити, що ваша відповідь є найбільш правильною. Підсумок для мене: set StartLimitIntervalSec=0і voilà.
Бенджамін

35

Так , є. Ви можете вказати, щоб повторити спробу через xкілька секунд у [Service]розділі,

[Service]
Type=simple
Restart=always
RestartSec=3
ExecStart=/path/to/script

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

systemctl daemon-reload

потім перезапустіть службу, щоб увімкнути зміни,

systemctl restart test

Як ви просили, дивлячись на документацію,

Restart=on-failure

звучить як гідна рекомендація.


Здається, це справді працює, дякую! Отже, щоб зрозуміти це краще, без RestartSecдирективи, systemdспроби кілька разів перезапускаються дуже швидко, а потім переходять у стан постійного відмови; щось, що не може статися, коли RestartSecвказано?
Бенджамін

Крім того, я помітив, що це затримує «нормальний» перезапуск мого працівника (я цілеспрямовано виходжу з робітника вишукано через кілька хвилин); чи є спосіб затримати лише невдалий перезапуск?
Бенджамін

@Benjamin дивіться мої оновлення
Rahul

@Benjamin Ви можете перевірити тут, щоб отримати більше параметрів.
Рахул

3
Судячи з доктора , alwaysце сукупність on-failure, тому це не допоможе!
Бенджамін

5

systemd відмовляється від спроби перезапустити його

Ні. Systemd відмовляється від спроби перезапустити його на деякий час . Це чітко показано в журналі, який ви постачаєте:

14 червня 11:25:51 localhost systemd [1]: test.service: Помилка з результатом 'start-limit' .

Це обмеження швидкості при натисканні.

Тривалість часу визначається в сервісному блоці, використовуючи StartLimitIntervalSec=налаштування. Кількість запусків, необхідних протягом цього інтервалу, щоб запустити механізм обмеження швидкості, задається через StartLimitBurst=налаштування. Якщо ніщо у вашій системі не відрізняється від ванільного systemd, включаючи типові параметри для цих двох налаштувань, це 5 разів протягом 10 секунд.

StartLimitIntervalSec=0вимикає обмеження швидкості, тому systemd буде намагатися навіки, а не здаватись. Але зробити вашу послугу або не виходити так часто, або простоювати між виходами та перезапусками, щоб вона не перевищувала поріг обмеження швидкості, є кращим підходом.

Зауважте, що обмеження ставок не має значення, як закінчилася ваша послуга. Він запускає кількість спроб запустити / перезапустити, незалежно від їх причини.

Подальше читання


5
Схоже, відмовляється назавжди, хоча: "Активне: не вдалось (Результат: стартовий ліміт) з ср. 2016-06-15 01:21:24 CEST; 12 год тому". Він залишається в такому стані, і сценарій більше ніколи не виконується. Я спробував налаштування вручну StartLimitIntervalSec=10і StartLimitIntervalSec=5, не пощастило.
Бенджамін

5
Він заздалегідь відмовляється постійно. Див. Github.com/systemd/systemd/isissue/2416 .
Адам Гуд

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