Systemd Timers против Cron: Выбираем правильный планировщик

Сравните cron и systemd-таймеры, чтобы выбрать правильный планировщик Linux для простых задач, сервисов, ведения журналов и управления зависимостями.

Systemd-таймеры против Cron: выбор правильного планировщика

Когда вашему Linux-серверу необходимо выполнять резервное копирование, очистку, проверку работоспособности или формирование отчетов по расписанию, вы обычно выбираете между cron и systemd-таймерами. Cron по-прежнему прост и переносим. Systemd-таймеры лучше подходят, когда задача ведет себя как управляемый сервис и требует ведения журналов, зависимостей или контроля ресурсов.

Правильный выбор зависит от используемой машины, поведения задачи при сбоях и необходимого уровня операционной видимости.

Понимание заданий Cron

cron — это планировщик заданий, основанный на времени, в Unix-подобных операционных системах. Он позволяет пользователям планировать выполнение команд или скриптов с заданной периодичностью в фиксированное время, даты или интервалы. Демон cron (crond) работает в фоновом режиме и проверяет файлы crontab на наличие запланированных заданий.

Как работает Cron

Каждый пользователь может иметь свой собственный файл crontab, управляемый с помощью команды crontab. Общесистемные задания обычно настраиваются в /etc/crontab или файлах внутри /etc/cron.d/.

Запись в crontab имеет следующий формат:

* * * * * command_to_execute
│ │ │ │ │
│ │ │ │ └───── День недели (0 - 6) (Воскресенье=0 или 7)
│ │ │ └─────── Месяц (1 - 12)
│ │ └───────── День месяца (1 - 31)
│ └─────────── Час (0 - 23)
└───────────── Минута (0 - 59)

Пример: Чтобы запускать скрипт резервного копирования каждый день в 2:00 ночи:

0 2 * * * /usr/local/bin/backup.sh

Преимущества Cron

  • Повсеместность: Доступен практически на всех Unix-подобных системах.
  • Простой синтаксис: Формат crontab относительно легко выучить для базового планирования.
  • Пользовательские задания: Легко настраивать задания для отдельных пользователей.

Недостатки Cron

  • Ограниченная гибкость: В основном основан на фиксированных временных интервалах. Обработка сложных зависимостей или планирования, управляемого событиями, затруднена.
  • Отсутствие управления зависимостями: Невозможно легко определить, что задание должно запускаться только после успешного завершения другого задания.
  • Отсутствие контроля ресурсов: Предоставляет мало или совсем не контролирует ресурсы (ЦП, память), потребляемые запланированными заданиями.
  • Ведение журналов и мониторинг: Часто полагается на почтовый вывод, syslog или явное перенаправление в команде.
  • Интеграция с unit-файлами: Не интегрирован напрямую с возможностями управления сервисами systemd.

Понимание Systemd-таймеров

systemd-таймеры — это более продвинутый и гибкий способ планирования задач, использующий возможности unit-файлов systemd. Вместо отдельного демона, systemd-таймеры управляются как часть самой системы инициализации systemd.

Как работают Systemd-таймеры

systemd-таймеры состоят из двух unit-файлов:

  1. Сервисный unit (.service): Определяет задачу или команду для выполнения.
  2. Unit таймера (.timer): Определяет, когда должен быть активирован соответствующий сервисный unit.

Эти файлы обычно размещаются в /etc/systemd/system/ или ~/.config/systemd/user/.

Пример: Планирование скрипта очистки для ежедневного запуска в 3:00 утра.

Сначала создайте сервисный файл (cleanup.service):

# /etc/systemd/system/cleanup.service

[Unit]
Description=Ежедневная задача очистки

[Service]
Type=oneshot
ExecStart=/usr/local/bin/cleanup.sh

Затем создайте файл таймера (cleanup.timer):

# /etc/systemd/system/cleanup.timer

[Unit]
Description=Запускать задачу очистки ежедневно

[Timer]
# Запустить через 25 минут после загрузки, а затем ежедневно в 3:00 утра
OnBootSec=25min
OnCalendar=*-*-* 03:00:00
# Альтернатива: Запускать через 24 часа после последнего выполнения
# OnUnitActiveSec=24h

[Install]
WantedBy=timers.target

После создания этих файлов перезагрузите systemd, включите таймер для будущих загрузок и запустите его сейчас:

sudo systemctl daemon-reload
sudo systemctl enable cleanup.timer
sudo systemctl start cleanup.timer

Вы можете проверить статус таймера и время его следующего срабатывания с помощью:

sudo systemctl status cleanup.timer

Ключевые директивы systemd-таймеров:

  • OnCalendar=: Задает время календарного события (похоже на синтаксис cron, но более мощный).
    • *-*-* 03:00:00: Ежедневно в 3:00 утра.
    • Mon..Fri *-*-* 09:00:00: По будням в 9:00 утра.
    • hourly: Каждый час.
    • daily: Раз в день.
    • weekly: Раз в неделю.
    • monthly: Раз в месяц.
    • yearly: Раз в год.
  • OnBootSec=: Запускает через указанное время после загрузки системы.
  • OnUnitActiveSec=: Запускает через указанное время после последней активации соответствующего unit (сервиса).
  • OnUnitInactiveSec=: Запускает через указанное время после того, как соответствующий unit (сервис) стал неактивным.
  • AccuracySec=: Насколько точным должен быть таймер. Более низкие значения могут потреблять больше энергии.
  • Persistent=: Для календарных таймеров значение true указывает systemd наверстать упущенное, если запланированный запуск был пропущен, пока таймер был неактивен, например, когда машина была выключена.

Преимущества Systemd-таймеров

  • Интеграция с systemd: Бесшовная интеграция с управлением сервисами systemd, ведением журналов (journalctl), контролем ресурсов и управлением зависимостями.
  • Гибкость: Поддерживает различные варианты планирования помимо фиксированных интервалов, включая календарные события, относительное время после загрузки и относительное время после предыдущей активации.
  • Управление зависимостями: Может определять зависимости от других unit-ов systemd (например, доступность сети).
  • Контроль ресурсов: Может использовать cgroups systemd для ограничения ресурсов (ЦП, память).
  • Ведение журналов: Интегрирован с journald для всестороннего и централизованного ведения журналов.
  • Обработка ошибок: Может использовать поведение сервисного unit, такое как Restart=, OnFailure= и упорядочивание зависимостей, если эти шаблоны подходят для задачи.
  • Осведомленность о состоянии: Может отслеживать, когда задание должно было запуститься, и выполнить его при запуске системы, если установлено Persistent=true.

Недостатки Systemd-таймеров

  • Более крутая кривая обучения: Синтаксис и концепции unit-файлов systemd могут быть более сложными для новичков, чем cron.
  • Зависимость от Systemd: Требуется система, работающая под управлением systemd (большинство современных дистрибутивов Linux это делают).

Systemd-таймеры против Cron: сводка ключевых различий

Особенность Задания Cron Systemd-таймеры
Управление Команда crontab, системные файлы Команда systemctl, unit-файлы
Планирование Фиксированные минута, час, день, месяц, день недели Календарные события, относительное время, на основе загрузки
Интеграция Отдельный демон Интегрирован с systemd
Ведение журналов Почта, перенаправление скрипта journald
Зависимости Нет Зависимости unit-ов systemd
Контроль ресурсов Нет cgroups systemd
Обработка ошибок Базовая Обработка сбоев сервисного unit
Отслеживание состояния Ограниченное Опция Persistent=
Сложность Проще для базовых задач Более мощный, более крутая кривая обучения

Когда выбирать какой планировщик

Выбирайте Cron, когда:

  • Вы работаете на очень старой или минимальной системе, которая не использует systemd.
  • Вам нужно запланировать очень простую, разовую задачу с фиксированным повторяющимся расписанием, и вы ставите простоту выше продвинутых функций.
  • Вам нужно быстрое расписание для команды, которая уже обрабатывает собственное ведение журналов и ошибки.

Выбирайте Systemd-таймеры, когда:

  • Вы работаете на современном дистрибутиве Linux, использующем systemd.
  • Вам нужен больший контроль над тем, когда выполняется задание (например, относительно загрузки, относительно последнего запуска, после поднятия сети).
  • Вам требуется лучшее ведение журналов, мониторинг и обработка ошибок.
  • Вы хотите управлять выполнением заданий с помощью мощных функций управления сервисами systemd, включая контроль ресурсов и управление зависимостями.
  • Вы уже управляете другими сервисами с помощью systemd и хотите использовать единый подход к планированию.
  • Ваши задачи имеют зависимости от других системных сервисов или событий.

Практическое эмпирическое правило

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

Ночное резервное копирование — хороший пример. На небольшом устаревшем сервере 0 2 * * * /usr/local/bin/backup.sh может быть достаточно. На production-хосте на базе systemd backup.service плюс backup.timer дают вам более четкий статус, журналы, наверстывание после загрузки с Persistent=true и более чистый путь для добавления зависимостей в будущем.