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=true systemd пишет время последнего срабатывания
на диск и догоняет пропущенный запуск после загрузки. Для машин, которые
не работают круглосуточно, это главная причина переходить.
Машина, простоявшая неделю, догонит один запуск. Не семь.
Разброс времени запуска, чтобы двадцать машин не пошли в один репозиторий одновременно. Считается детерминированно от machine-id, поэтому сдвиг у каждой машины стабильный и не меняется при перезагрузке. В cron то же самое приходилось делать руками, разводя задачи по минутам.
Проверяется одной командой:
systemd-analyze calendar 'Mon *-*-* 04:30:00'
Выводит нормализованное выражение и ближайшее срабатывание.
Два файла вместо одной строки многословнее. На одиночном сервере с тремя задачами cron остаётся разумным выбором. Переход окупается там, где задач много, они разного веса и машины иногда выключаются.