systemd обрывает завершение worker: как выбрать TimeoutStopSec

Worker получает сигнал остановки, прекращает брать новые задания и начинает сохранять результат текущего. В обычном запуске это занимает около двадцати секунд. Под systemd в журнале виден старт завершения, затем сообщение о timeout и принудительное убийство процесса. Теперь проблема находится между двумя бюджетами времени: приложения и менеджера служб.

Graceful shutdown требует конечного промежутка, в который программа может закончить работу. Менеджер тоже не должен ждать бесконечно: зависший процесс задержит остановку или обновление. Поэтому полезно сначала выяснить, что приложение делает после SIGTERM, и только затем задавать время ожидания. Увеличивать лимит наугад значит откладывать тот же вопрос до следующего релиза.

Согласовать два срока

Допустим, worker ограничивает завершение текущего задания тридцатью секундами, после чего фиксирует статус и выходит. Для такого поведения можно дать службе сорок секунд, оставив запас на финальную запись и освобождение ресурсов.

[Service]
TimeoutStopSec=40s

Это фрагмент drop-in, а не требование для любого worker. Значение выбирают по максимальному допустимому завершению конкретной операции. Если обработка может занимать часы, часто лучше сохранять контрольную точку и возвращать задание в очередь, чем удерживать обновление часами. Длительность штатного расчёта и допустимая длительность остановки необязательно совпадают.

В стандартной схеме остановки после истечения бюджета оставшиеся процессы могут получить SIGKILL. Его приложение обработать не сможет. При наличии ExecStop проверьте и эту команду: её ожидание тоже связано с TimeoutStopSec. Не добавляйте в ExecStop долгую команду отправки сигнала, которая сама завершается раньше фактической остановки и оставляет непонятный второй этап.

Что измерять при проверке

На учебном стенде подготовьте задание с контролируемой длительностью. Запишите время получения SIGTERM, прекращения приёма работы и завершения процесса. Затем остановите службу и сопоставьте сообщения приложения с журналом systemd. Команда systemctl show worker.service -p TimeoutStopUSec покажет применённый менеджером бюджет. Настройка в файле может отличаться от активной, если забыли daemon-reload.

Проверьте два сценария. В первом работа укладывается в срок: процесс выходит сам, а результат остаётся согласованным. Во втором операция намеренно не заканчивается: менеджер завершает её в установленный срок, а после запуска worker корректно распознаёт незавершённое задание. Только первый сценарий не показывает, что произойдёт при настоящем зависании.

В инструкции к обновлению полезно указать максимальное время остановки и действие при его превышении. Если приложение завершилось быстро, но потеряло результат, менять TimeoutStopSec уже бесполезно: нужно разбирать протокол сохранения и подтверждения работы. Таймер даёт приложению время, а корректное завершение остаётся частью приложения.

Продолжить практику

За одной настройкой unit обычно стоит весь путь сопровождения приложения: отдельный пользователь, права на данные, сеть, журналы и повторяемые операции. В программе курса «Linux и Bash для DevOps-инженеров» эти задачи собраны вокруг учебного сервера с приложением под systemd. В практике предусмотрены Bash-скрипты проверки состояния и резервного копирования, а также runbook для воспроизводимых поломок. Это подходящее продолжение, если хочется связать отдельные команды в понятный порядок диагностики.

Посмотреть программу курса

Источник: официальная документация.

Другие задачи по теме: Запуск и жизненный цикл служб systemd.

Продолжить на практике

  • Linux и Bash для DevOps-инженеров ↗

    Linux для работы с серверами: процессы, права, systemd, сеть, диски и логи. Автоматизируйте повседневные задачи на Bash и разберите типичные сбои сервиса — от занятого порта до переполненного диска.