systemd timers вместо cron: планировщик задач по-современному

Linux · Автоматизация3 октября 20267 мин чтения

cron делает свою работу десятилетиями, и никуда не денется. Но у systemd timers есть несколько преимуществ, из-за которых на новых серверах имеет смысл выбирать именно их. Разберёмся на практическом примере — ежедневный бэкап.

Чем таймер лучше cron

Шаг 1: скрипт

Начнём с того, что должен делать cronjob, — просто скрипта:

#!/bin/bash
# /usr/local/bin/backup.sh
set -euo pipefail
rsync -a --delete /var/www/ /mnt/backup/www/
echo "$(date -Is) backup done"

set -euo pipefail — обязательный минимум: скрипт упадёт при первой ошибке, а не продолжит молча портить данные дальше.

Шаг 2: service-юнит

Таймер сам ничего не запускает — он будит сервис. Создаём /etc/systemd/system/backup.service:

[Unit]
Description=Daily backup of web files
RequiresMountsFor=/mnt/backup

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

Обратите внимание на две детали. Type=oneshot — типовой тип для разовых задач. А RequiresMountsFor=/mnt/backup гарантирует, что бэкап не запустится «в никуда», если диск не смонтирован. Nice и I/O-класс опускают задачу в фон, чтобы бэкап не мешал веб-серверу под нагрузкой.

Шаг 3: timer-юнит

Рядом кладём backup.timer — имя должно совпадать с сервисом:

[Unit]
Description=Run backup daily

[Timer]
OnCalendar=*-*-* 03:30:00
Persistent=true
RandomizedDelaySec=600

[Install]
WantedBy=timers.target

Пояснения к расписанию:

Шаг 4: активация и проверка

systemctl daemon-reload
systemctl enable --now backup.timer
systemctl list-timers backup.timer

Последняя команда показывает, когда таймер сработает в следующий раз — проверка расписания без ожидания до трёх ночи. Немедленный прогон задачи:

systemctl start backup.service
journalctl -u backup.service -e

Календарные выражения

Формат OnCalendar достаточно гибкий, вот частые случаи и их аналоги в cron:

РасписаниеOnCalendarcron
Каждые 15 минут*:0/15*/15 * * * *
Ежедневно в 3:30*-*-* 03:30:0030 3 * * *
По будням в 9:00Mon..Fri *-*-* 09:00:000 9 * * 1-5
Первое число месяца*-*-01 00:00:000 0 1 * *

Проверить выражение до установки поможет systemd-analyze calendar "Mon..Fri 09:00" — он покажет дату ближайшего срабатывания.

Когда cron всё-таки уместнее

Таймеры требуют двух файлов вместо одной строки — это ощутимо на простых задачах. Если у вас пара crontab-записей на домашнем сервере, который работает 24/7, и логи не нужны — cron честнее. А вот для задач с зависимостями, лимитами и требованием «не потерять запуск» systemd timer — более предсказуемый инструмент, плюс вся инфраструктура наблюдения (systemctl status, journald, prometheus-экспортёры юнитов) работает с ним нативно.