opsjournal.net

Перевёл cron-задачи на systemd timers

· linuxsystemd

На домашнем сервере накопилось штук пятнадцать задач в crontab: бэкапы, чистка, синхронизация. Проблема была не в самом cron, а в том, что я не видел, какая задача упала и когда. Логи уходили в почту, которую никто не читал. Перенёс всё на systemd timers и не жалею.

Что даёт timer по сравнению с cron

Минимальный пример

Два файла. Сервис описывает, что запускать:

# /etc/systemd/system/cleanup.service
[Unit]
Description=Очистка временных файлов

[Service]
Type=oneshot
ExecStart=/usr/local/bin/cleanup.sh
Nice=10
IOSchedulingClass=idle

Таймер описывает, когда:

# /etc/systemd/system/cleanup.timer
[Unit]
Description=Ежедневная очистка

[Timer]
OnCalendar=*-*-* 04:15:00
RandomizedDelaySec=15m
Persistent=true

[Install]
WantedBy=timers.target
systemctl daemon-reload
systemctl enable --now cleanup.timer
systemctl list-timers cleanup.timer

Проверить расписание до того, как ждать сутки

systemd-analyze calendar показывает, когда сработает выражение:

$ systemd-analyze calendar "Mon..Fri *-*-* 09:00"
  Original form: Mon..Fri *-*-* 09:00
Normalized form: Mon..Fri *-*-* 09:00:00
    Next elapse: ...

Уведомление о падении

Самое полезное: OnFailure=. Я завёл шаблонный сервис, который шлёт сообщение в Telegram-бота, и подключил его ко всем задачам одной строкой:

[Unit]
OnFailure=notify-failure@%n.service

Теперь упавший бэкап я вижу в течение минуты, а не через месяц.

Где cron всё ещё удобнее

Для разовой задачи «запустить вот это каждые пять минут» два файла выглядят избыточно. Тогда выручает systemd-run --on-calendar='*:0/5' /path/script.sh: он создаёт временный таймер без файлов.