golodyaev.ru ЗаметкиО сайте

Таймеры systemd вместо cron

19 июня 2025

Перевёл десяток регулярных задач. Ниже то, что пригодилось на практике.

Лимиты и журнал

Задача из таймера запускается обычным юнитом. У неё есть свой cgroup, свои лимиты, отдельный поток в журнале и код возврата, который видно в systemctl status. Ночной скрипт, который отъедает память, ограничивается одной строкой MemoryMax= в юните.

systemctl list-timers показывает прошлое и следующее срабатывание без раскопок в логах:

NEXT                        LEFT     LAST                        PASSED  UNIT
Fri 2025-06-20 03:00:00 MSK 8h left  Thu 2025-06-19 03:00:12 MSK 15h ago backup.timer

Persistent

С Persistent=true systemd пишет время последнего срабатывания на диск и догоняет пропущенный запуск после загрузки. Для машин, которые не работают круглосуточно, это главная причина переходить.

Машина, простоявшая неделю, догонит один запуск. Не семь.

RandomizedDelaySec

Разброс времени запуска, чтобы двадцать машин не пошли в один репозиторий одновременно. Считается детерминированно от machine-id, поэтому сдвиг у каждой машины стабильный и не меняется при перезагрузке. В cron то же самое приходилось делать руками, разводя задачи по минутам.

OnCalendar

Проверяется одной командой:

systemd-analyze calendar 'Mon *-*-* 04:30:00'

Выводит нормализованное выражение и ближайшее срабатывание.

Когда не нужно

Два файла вместо одной строки многословнее. На одиночном сервере с тремя задачами cron остаётся разумным выбором. Переход окупается там, где задач много, они разного веса и машины иногда выключаются.

Все заметки