Найти в Дзене
Записки сисадмина

Linux. Systemd timers. Ищем замену cron

Оглавление

В IT мире существует две парадигмы: «Если нужно что-то сделать больше двух раз - автоматизируй это.» и «Автоматизация подразумевает под собой полное отсутствие человека в цепочке выполнения.»

Если тебе нужно производить одни и те же действия, и ты написал для этого скрипт - молодец, но ты только на половине пути. Убери из этой цепочки инженера, и твой скрипт некому будет запускать.

Тут нам на помощь приходят планировщики. Каждый, кто хоть немного работал с linux системами, знает про надежный и старый cron. Но пора дать дорогу молодым и свежим, поэтому сегодня мы поговорим про самую очевидную альтернативу: systemd таймеры.

Ранее мы уже создавали своего уникального systemd демона, который работал в режиме реального времени, теперь будем создавать инструмент для управления им.

Таймеры systemd – это механизм, который позволяет выполнять определённые действия по расписанию или в ответ на события. Они часто используются для автоматизации задач в системах на базе Linux, где используется init-система systemd.

Так в чем же их преимущество перед cron?

1. Интеграция с systemd:

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

2. Удобство в управлении:

- Команды управления таймерами (например, start, stop, enable) используют те же средства, что и для других юнитов systemd. Это упрощает работу и делает администрирование более однородным.

3. Более гибкое планирование:

- Systemd таймеры поддерживают более сложные временные интервалы, такие как "через каждые 10 минут", "каждый первый понедельник месяца" и другие, что может быть труднее реализовать в cron. Также обходится ограничение cron, который может запускать задачи минимум раз в минуту.

4. Состояние и журнал:

- Systemd предоставляет встроенные механизмы для отслеживания статуса таймеров и журналирования их выполнения, что облегчает мониторинг и отладку.

5. Параметры запуска:

- В таймерах systemd можно задать параметры, такие как ограничения по памяти и CPU, а также задать условия для запуска, например, после определённых других служб.

6. Состояние:

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

7. Активация на основе событий:

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

Управление Таймерами

  • Загруженные в систему таймеры

Чтобы посмотреть все активные таймеры, вводим команду:

systemctl list-timers

Чтобы вывести абсолютно все таймеры со статусом "enabled', добавляем ключ --all

systemctl list-timers --all
-2

Вывод всех таймеров по шабону:

systemctl list-timers PATTERN
systemctl list-timers --allPATTERN

Вывод всех таймеров по состоянию:

systemctl list-timers --state=STATE

  • Обозначение таблицы таймеров.
-3

NEXT - Полная дата и время следующего срабатывания таймера.

LEFT - Время до следующего срабатывания.

LAST - Полная дата и время последнего срабатывания.

PASSED - Прошедшее время с последнего срабатывания.

UNIT - Имя таймера.

ACTIVATES - Сервис, который этот таймер активирует.

  • Запуск таймеров.

Управление таймерами производится точно так же, как и демонами systemd. Чтобы запустить, перезапустить, или остановить таймер, вводим:

systemctl start TIMER.timer
systemctl restart TIMER.timer
systemctl stop TIMER.timer

Добавить, или удалить таймер из автозагрузки:

systemctl enable TIMER.timer
systemctl disable TIMER.timer

Вывести содержимое файла таймера:

systemctl cat TIMER.timer
-4

Вывести статус таймера:

systemctl status TIMER.timer
-5

Типы таймеров

В systemd есть всего два типа таймеров: те, которые зависят от определенных событий (monotonic), и те, которые активируются по определенному расписанию (real-time)

Real-time таймеры.

Обозначаются параметром "OnCalendar" в формате:

"OnCalendar=DayOfWeek Year-Month-Day Hour:Minute:Second"

1. Дни недели: Sun, Mon, Tue, Wed, Thu, Fri, Sat

Можно указывать один день недели, несколько конкретных дней, либо интервал дней недели:

OnCalendar=Mon *-*-* 00:00:00

Запуск задания в понедельник в полночь.

OnCalendar=Mon,Tue *-*-* 00:00:00

Запуск задания в понедельник и вторник в полночь.

OnCalendar=Mon..Thu *-*-* 00:00:00

Запуск задания с понедельника по четверг в полночь.

2. Дата: записывается в формате гггг-мм-дд. Допускается использования звездочки (*) для указания каждого дня/месяца/года

OnCalendar=2025-02-10 00:00:00

Запуск задачи 10 февраля 2025 года.

OnCalendar=2025-02-* 00:00:00

Запуск задачи каждый день февраля 2025 года в полночь.

3. Время: Записывается в формате чч:мм:сс. Также допускается использования звездочки (*).

OnCalendar=*:*:00

Запуск задачи каждую минуту в 00 секунд.

OnCalendar=*:*:*

Запуск задачи каждую секунду (не рекомендуется, расскажу об этом ниже)

OnCalendar=10:00:00

Запуск задачи каждый день в 10:00.

4. Дополнительные возможности real-time таймеров:

  • Допускается пропуск директив "дни недели" и "дата", если это не нужно:
OnCalendar=Mon..Sun *-*-* 00:00:00

Даст тот же результат, что и:

OnCalendar=00:00:00

  • Допускается использование нескольких директив OnCalendar:
OnCalendar=Mon..Fri *-*-* 00:00:00
OnCalendar=Sat,Sun *-*-* 02:00:00

Запуск задачи по будням в полночь, а по выходным - в 2 часа ночи.

  • Настройка точности срабатывания:
OnCalendar=*:*:0/20
AccuracySec=1s

Запуск задачи каждые 20 секунд с точностью до секунды.

Если указать AccuracySec=1us, запуск будет с точностью до миллисекунд.

Важно помнить, что увеличение точности запуска будет сильнее нагружать вашу систему, так что не рекомендую использовать это без необходимости.

Monotonic таймеры

Таймеры, которые срабатывают через указанное время после какого-либо события.

  • OnActiveSec. Срабатывание после активации юнита (systemd сервиса).
OnActiveSec=10minutes

Таймер отработает через 10 минут после того, как сервис, к которому он привязан, будет запущен.

  • OnBootSec. Срабатывание после запуска всей системы.
OnBootSec=2hours

Таймер отработает через 2 часа после запуска сервера.

  • OnStartupSec. Срабатывание после запуска менеджера сервисов.
OnStartupSec=5minutes 10 seconds

Таймер отработает через 5 минут 10 секунд после запуска менеджера сервисов. Для сервисов, запускаемых из под root, это будет равнозначно OnActiveSec. Советую использовать для сервисов конкретного юзера, для которого менеджер сервисов запускается при логине пользователя.

  • OnUnitActiveSec. Срабатывание после последнего запуска юнита.
OnUnitActiveSec=7minutes

Таймер отработает через 7 минут после ПОСЛЕДНЕГО запуска сервиса. В отличии от OnActiveSec, таймер будет обновляться каждый раз после перезапуска сервиса.

OnUnitInactiveSec. Срабатывание после последней остановки сервиса.

OnUnitInactiveSec=2minutes 30 seconds

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

В следующей статье будем создавать свой собственный таймер и разбираться в нюансах его запуска.