Как создавать таймеры systemd и управлять ими
Создавайте, включайте, отслеживайте и устраняйте неполадки модулей таймеров systemd с практическими примерами `.timer`, `.service`, `systemctl` и `journalctl`.
Как создавать и управлять модулями таймеров systemd
Модули таймеров systemd планируют выполнение задач в Linux без использования cron. Если вашему серверу необходимо запускать резервное копирование, задачу очистки, проверку работоспособности или отчет в определенное время, systemd-таймер предоставляет планирование, изоляцию служб, обработку зависимостей и ведение журналов в одном месте.
Ключевая идея проста: файл .timer указывает, когда запускать, а файл .service указывает, что запускать. Такое разделение упрощает проверку таймеров с помощью systemctl и отладку с помощью journalctl.
Понимание структуры модуля таймера systemd
Модуль таймера systemd всегда связан с соответствующим модулем службы (или другим типом модуля), который он должен активировать. Сам модуль таймера определяет когда должен быть активирован связанный модуль, а модуль службы определяет какое действие выполнить. Оба модуля обычно находятся в одном каталоге, часто /etc/systemd/system/ для пользовательских модулей.
Типичный файл модуля таймера имеет расширение .timer, а связанный с ним файл модуля службы — .service. Например, если вы хотите запланировать задачу, определенную в mytask.service, вы создадите файл mytask.timer.
Пример: mytask.timer
[Unit]
Description=Run my custom task daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.target
Разберем ключевые разделы:
Раздел
[Unit]:Description: Понятное человеку описание таймера. Это полезно для идентификации в выходных данных статуса.
Раздел
[Timer]: Это ядро модуля таймера, определяющее расписание.OnCalendar=daily: Эта директива указывает, когда таймер должен активироваться.daily— это сокращение для полуночи каждого дня. Другие примеры:hourly: Каждый час.weekly: Каждую неделю (эквивалентноMon *-*-* 00:00:00).Sun *-*-* 10:00: Каждое воскресенье в 10:00.*-*-15 14:30: 15-го числа каждого месяца в 14:30.Mon..Fri *-*-* 09:00: По будням в 9:00.
Persistent=true: Если установлено значениеtrue, таймер активируется как можно скорее, если событие произошло, когда система была выключена. Для таймеровOnCalendarэто означает, что если система была выключена в запланированное время, таймер сработает после загрузки системы и активации таймера.OnBootSec=: Активирует таймер через указанное время после загрузки системы. Например,OnBootSec=15minсработает через 15 минут после загрузки.OnUnitActiveSec=: Активирует таймер через указанное время после последней активации связанного модуля. Например,OnUnitActiveSec=1hпланирует следующий запуск через час после последней активации связанной службы.OnUnitInactiveSec=: Активирует таймер через указанное время после того, как связанный модуль стал неактивным.AccuracySec=: Определяет точность таймера. Systemd пытается пробудить систему для таймеров только в том случае, если событие находится в пределах этого временного окна, что помогает экономить энергию. По умолчанию1min.RandomizedDelaySec=: Добавляет случайную задержку к срабатыванию таймера, до указанной длительности. Полезно для распределения нагрузки.
Раздел
[Install]: Этот раздел определяет, как можно включить модуль таймера.WantedBy=timers.target: Эта директива гарантирует, что при включении таймера он становится частьюtimers.target, который является стандартной целью, включающей все активные таймеры. Это означает, что таймер будет автоматически запускаться при загрузке после включения.
Пример: mytask.service
[Unit]
Description=My custom task service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/my_custom_script.sh
User=myuser
Group=mygroup
[Install]
WantedBy=multi-user.target
Раздел
[Unit]:Description: Описание службы.
Раздел
[Service]: Определяет саму службу.Type=oneshot: Подходит для задач, которые выполняются один раз и завершаются. Существуют другие типы для долго работающих демонов.ExecStart: Команда для выполнения. Убедитесь, что скрипт имеет права на выполнение.User/Group: Указывает пользователя и группу, от имени которых должна выполняться команда. Рекомендуется не запускать задачи от root, если это не абсолютно необходимо.
Раздел
[Install]: Обычно не требуется для службы oneshot, которая должна запускаться только по таймеру. Включайте таймер, а не службу.
Создание и включение модулей таймеров
Выполните следующие шаги для создания и управления модулями таймеров systemd:
Создайте файл модуля службы: Определите задачу в файле
.service. Поместите его в/etc/systemd/system/(или~/.config/systemd/user/для пользовательских таймеров).sudo nano /etc/systemd/system/mytask.serviceВставьте пример содержимого службы выше и сохраните.
Создайте файл модуля таймера: Определите расписание в соответствующем файле
.timer. Поместите его в тот же каталог, что и файл службы.sudo nano /etc/systemd/system/mytask.timerВставьте пример содержимого таймера выше и сохраните.
Перезагрузите демон systemd: После создания или изменения файлов модулей необходимо сообщить systemd о необходимости перезагрузки конфигурации.
sudo systemctl daemon-reloadВключите таймер: Чтобы таймер автоматически запускался при загрузке, включите его.
sudo systemctl enable mytask.timerПримечание: НЕ включайте файл службы, если он предназначен только для запуска по таймеру.
Запустите таймер: Запустите таймер немедленно. Затем он будет работать в соответствии со своим расписанием.
sudo systemctl start mytask.timer
Управление и мониторинг модулей таймеров
Systemd предоставляет несколько команд systemctl для управления и мониторинга таймеров:
Список всех таймеров: Просмотр всех активных и неактивных таймеров.
systemctl list-timersЭта команда выводит результат, подобный:
NEXT LEFT LAST PASSED UNIT ACTIVATES Tue 2023-10-27 08:00:00 UTC 10h left Wed 2023-10-26 08:00:00 UTC 14h ago mytask.timer mytask.serviceЗдесь показано, когда таймер должен сработать в следующий раз, сколько времени осталось, когда он сработал в последний раз и какую службу он активирует.
Список таймеров для конкретного модуля: Если вы хотите увидеть таймеры, связанные с определенной службой.
systemctl list-timers --all | grep mytask.serviceПроверка статуса таймера: Получение подробной информации о конкретном таймере.
systemctl status mytask.timerЭто покажет, активен ли таймер, когда он должен сработать в следующий раз, а также последние записи журнала.
Просмотр журналов службы: Чтобы увидеть вывод и статус задачи, выполненной таймером, проверьте журналы связанной службы.
journalctl -u mytask.serviceВы также можете следить за журналами в реальном времени:
journalctl -f -u mytask.serviceОстановка таймера: Если вам нужно временно отключить таймер.
sudo systemctl stop mytask.timerОтключение таймера: Чтобы предотвратить запуск таймера при загрузке и остановить его, если он работает.
sudo systemctl disable --now mytask.timer
Расширенные конфигурации таймеров
Установка определенных интервалов
Вместо daily или hourly вы можете определить более точные интервалы:
- Каждые N минут:
OnUnitActiveSec=15min(запускается через 15 минут после последней активации службы). - Определенное время:
OnCalendar=*-*-* 02:30:00(запускается ежедневно в 2:30). - Комбинирование условий:
OnCalendar=Mon..Fri *-*-* 08:00:00(запускается по будням в 8:00).
Использование AccuracySec для экономии энергии
Если ваша задача не требует выполнения в точный момент, рассмотрите возможность использования AccuracySec. Например, AccuracySec=5min сообщает systemd, что можно разбудить систему в течение 5 минут от запланированного времени. Это позволяет systemd группировать события таймеров и потенциально дольше удерживать систему в состоянии низкого энергопотребления.
[Timer]
OnCalendar=hourly
AccuracySec=5min
Persistent vs. WakeSystem
Persistent=trueгарантирует, что если событиеOnCalendarбыло пропущено из-за выключения системы, оно выполнится один раз при следующей загрузке. Это важно для задач, которые нельзя пропускать.WakeSystem=trueпросит systemd разбудить систему из режима ожидания для таймера, если система и оборудование это поддерживают. Это не то же самое, что решение о том, работает ли машина от сети или от батареи.
Таймеры vs. Cron
| Особенность | Таймеры systemd | Cron |
|---|---|---|
| Интеграция | Глубокая интеграция со службами systemd, целями | Автономная утилита |
| Планирование | Гибкое (календарное, относительное, на основе загрузки) | В основном выражения на основе времени |
| Ведение журнала | Централизованное через journalctl |
Разрозненное (/var/log/syslog, /var/log/cron.log) |
| Обработка ошибок | Можно привязать действия к сбоям служб | Базовые уведомления по почте |
| Зависимости | Может зависеть от активности других служб | Ограниченные |
| Выполнение | Может выполняться от имени конкретных пользователей, групп | Может выполняться от имени конкретных пользователей через crontab |
| Управление питанием | Может быть оптимизировано для экономии энергии (AccuracySec) |
Менее прямой контроль |
Когда выбирать таймеры systemd:
- Когда требуется более тесная интеграция с другими службами systemd.
- Когда централизованное ведение журнала и более простая отладка являются приоритетом.
- Когда требуются более продвинутые опции планирования (например, время с последнего запуска).
- Для задач, связанных с состоянием системы или управлением питанием.
Когда cron может быть предпочтительнее:
- Для очень простых автономных задач в системах, не полностью использующих systemd.
- Для максимальной совместимости между различными дистрибутивами Linux и старыми системами.
Устранение распространенных неполадок
- Задача не выполняется:
- Проверьте статус таймера:
systemctl status mytask.timer. Ищите сообщенияActive: activeиTriggered.... - Проверьте журналы службы:
journalctl -u mytask.service. Убедитесь, что скрипт исполняемый и не содержит ошибок. - Проверьте синтаксис
OnCalendar: Используйтеsystemd-analyze calendar 'your-calendar-string'для тестирования. - Убедитесь, что таймер включен и запущен:
systemctl list-timers --all.
- Проверьте статус таймера:
- Задача выполняется слишком рано/поздно:
- Проверьте
AccuracySecиRandomizedDelaySec. - Убедитесь, что системные часы точны (
timedatectl status).
- Проверьте
- Ошибки разрешений:
- Подтвердите, что
UserиGroup, указанные в файле.service, имеют необходимые разрешения для скрипта и любых файлов, к которым он обращается. - Если пользователь не указан, по умолчанию используется root. Будьте осторожны с привилегиями root.
- Подтвердите, что
Заключение
Используйте systemd-таймер, когда задача относится к сервисному уровню машины: резервное копирование, задачи очистки, проверки мониторинга, хуки обновления сертификатов и другие операционные работы. Сначала создайте службу, затем создайте таймер, выполните systemctl daemon-reload, включите и запустите таймер, затем проверьте его с помощью systemctl list-timers --all и journalctl -u your.service.