Что останавливает мой пользовательский таймер systemd?

Я использую пользовательские таймеры systemd в качестве замены cron. У меня определенная программа настроена на выполнение каждые 20 минут. Программа не является демоном, зависит от сети и запускает ряд дочерних процессов. Однако я заметил, что таймер часто останавливается через несколько часов (или дней). Таймер по-прежнему активен, но программа больше не выполняется каждые 20 минут. pgrep показывает количество все еще активных процессов. Наблюдая за этим, я добавил JobTimeoutSec=3m в файл .service, ожидая, что процессы будут убиты, если они истекут.

systemctl status --user PROGRAM.service теперь выводит следующее, однако дочерние процессы все еще работают, и таймер больше не выполняет программу каждые 20 минут:

13 февраля 15:03:45 HOSTNAME systemd [1878]: истекло время ожидания задания PROGRAM.service / start.

13 февраля 15:03:45 HOSTNAME systemd [1878]: истекло время, начиная с ОПИСАНИЯ.

13 февраля 15:03:45 HOSTNAME systemd [1878]: Задание PROGRAM.service / start завершилось неудачно с результатом «тайм-аут».

Я предполагаю, что дочерние процессы программы останавливаются из-за сетевых проблем, и systemd не может их убить по истечении времени ожидания.

Любые предложения по решению этой проблемы, чтобы таймер продолжал работать должным образом?

Замена ExecStart=/path/to/program на ExecStart=/usr/bin/timeout 20m /path/to/program, похоже, решает эту проблему, но я хотел бы выяснить, почему только systemd этого не делает.


Отладочная информация

PROGRAM.service

[Unit]
Description=DESCRIPTION
After=network.target
PartOf=network-online.target
JobTimeoutSec=3m

[Service]
Type=oneshot
ExecStart=/path/to/program

[Install]
WantedBy=network-online.target

PROGRAM.timer

[Unit]
Description=Run PROGRAM.service every 20 minutes

[Timer]
OnCalendar=*:0/20

[Install]
WantedBy=timers.target

systemd --version выводит следующее:

systemd 219

+ PAM + AUDIT + SELINUX + IMA + APPARMOR + SMACK + SYSVINIT + UTMP + LIBCRYPTSETUP + GCRYPT -GNUTLS + ACL + XZ -LZ4 -SECCOMP + BLKID -ELFUTILS + KMOD -IDN


person Six    schedule 14.02.2016    source источник
comment
Я предлагаю перенести вопрос на unix.stackexchange.com   -  person Grzegorz Wierzowiecki    schedule 05.05.2016


Ответы (1)


Активный процесс

В systemd есть две важные вещи, которые, я думаю, вы затрагиваете в этом случае:

  1. Когда вы запускаете процесс с systemd, все дочерние процессы (по крайней мере, по умолчанию) входят в одну группу.

  2. Если какой-либо из этих дочерних элементов не умирает, считается, что процесс все еще (по крайней мере, в некоторой степени) выполняется.

Что это значит?

В описании таймера говорится:

Обратите внимание, что если устройство, которое нужно активировать, уже активировано в то время, когда истекает таймер, он не перезапускается, а просто остается включенным.

Другими словами, если через 20 минут какой-либо из ваших процессов все еще работает, система таймера ничего не перезапустит.

Почему в этом есть смысл ?!

CRON делал то же самое. Если бы ваш процесс все еще работал, он не перезапускал бы его снова и снова (потому что это просто заполнило бы память и, возможно, сломало бы многие другие вещи). Однако CRON не имел понятия о группе процессов. Поэтому, если ваш основной процесс действительно умер, предполагается, что он может его перезапустить.

Что такое решение systemd?

Предполагая, что вы не можете просто остановить дочерние процессы (хотя, поскольку вы использовали /usr/bin/timedout, вы, вероятно, можете?), Один из способов - использовать _ 4_ вариант, хотя я не рекомендую его:

KillMode=process

Это означает, что после остановки основного процесса считается, что служба остановлена.

Если установлено значение process, уничтожается только сам основной процесс.

Вы можете проверить, действительно ли это работает, поскольку в документации не сказано, что вся группа будет считаться мертвой ... Но по моему опыту, это работает.

Какое тогда решение лучше?

Поскольку я не рекомендую KillMode, должно быть другое решение. Дело в том, что у всех ваших процессов либо есть 20 минут для запуска (или любое количество времени, оставшееся на момент их создания), либо они будут препятствовать выполнению следующего запуска, что может быть нормальным время от времени, но, конечно, нет, если они остаются навсегда. Таким образом, можно было бы отредактировать эти процессы и убедиться, что они завершаются через некоторое время.

Однако по прошествии долгого времени может потребоваться убить эти процессы, и использование инструмента тайм-аута, как вы это сделали, может быть лучшим решением, если сами процессы не могут просто завершить вовремя < / em>. Хотя я бы предложил одну небольшую модификацию, которая заключается в использовании 19 мин. для тайм-аута, иначе вы можете пропустить следующее окно запуска.

ExecStart=/usr/bin/timeout 19m /path/to/program
person Alexis Wilke    schedule 27.08.2016