origin

Переваги таймерів Systemd

Покращене ведення журналів та моніторинг

  • Усі дії таймера реєструються за допомогою journald
  • Простий перегляд журналів за допомогою команди journalctl -u service-name
  • Інтеграція зі звітами про стан systemd

Управління залежностями

  • Можливість вказувати залежності від інших служб або стану системи
  • Запуск служб лише за умови виконання певних умов
  • Більш ефективний контроль над порядком виконання

Гнучке планування

  • Планування на основі календаря (подібно до cron)
  • Монотонні таймери (відносно часу завантаження, запуску тощо)
  • Можливість запуску служб за системними подіями

Управління ресурсами

  • Інтеграція з cgroups для обмеження ресурсів
  • Можливість встановлювати обмеження на використання процесора та пам'яті для кожної служби
  • Покращена ізоляція процесів

Обробка помилок

  • Політики автоматичного перезапуску
  • Повідомлення про помилки
  • Покращене відстеження помилок

Недоліки таймерів Systemd

Складність

  • Потрібно два файли (.service та .timer) замість одного рядка
  • Більш крута крива освоєння порівняно з cron
  • Більш розгорнута конфігурація

Сумісність

  • Працює лише на системах на базі systemd
  • Cron є більш універсальним для Unix-подібних систем

Таймери на рівні користувача

  • Для використання користувацьких таймерів необхідний прапор --user та увімкнена функція lingering
  • Трохи складніше налаштування для користувачів, що не мають прав суперкористувача

Базове налаштування: створення першого таймера Systemd

Крок 1: Створення файлу служби

Спочатку створіть файл служби, у якому визначено, що саме має виконуватися. Збережіть його під назвою /etc/systemd/system/backup-script.service:

[Unit]
Description=Daily Backup Script
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
User=backup
Group=backup
ExecStart=/usr/local/bin/backup.sh
StandardOutput=journal
StandardError=journal

# Resource limits
CPUQuota=50%
MemoryLimit=1G

Крок 2: Створення файлу таймера

Далі створіть відповідний файл таймера. Збережіть його під назвою /etc/systemd/system/backup-script.timer:

[Unit]
Description=Run backup script daily at 2 AM
Requires=backup-script.service

[Timer]
OnCalendar=daily
OnCalendar=*-*-* 02:00:00
Persistent=true
Unit=backup-script.service

[Install]
WantedBy=timers.target

Крок 3: Увімкніть і запустіть таймер

# Reload systemd to recognize new files
sudo systemctl daemon-reload

# Enable the timer to start on boot
sudo systemctl enable backup-script.timer

# Start the timer immediately
sudo systemctl start backup-script.timer

# Check timer status
sudo systemctl status backup-script.timer

# List all active timers
sudo systemctl list-timers --all

Типові налаштування таймера

Щогодини

[Timer]
OnCalendar=hourly
# Or more explicitly:
OnCalendar=*-*-* *:00:00

Кожні 15 хвилин

[Timer]
OnCalendar=*:0/15

У будні о 9:00

[Timer]
OnCalendar=Mon-Fri *-*-* 09:00:00

Щопонеділка о 3-й годині ночі

[Timer]
OnCalendar=Mon *-*-* 03:00:00

Через 5 хвилин після завантаження

[Timer]
OnBootSec=5min

Комбінація: щодня та після запуску системи

[Timer]
OnCalendar=daily
OnBootSec=10min
Persistent=true

Приклад міграції: з Crontab до таймера Systemd

Оригінальний запис у Crontab

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

Еквівалентна конфігурація Systemd

cleanup.service:

[Unit]
Description=Cleanup temporary files

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

cleanup.timer:

[Unit]
Description=Daily cleanup at 2 AM

[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true

[Install]
WantedBy=timers.target

Розуміння основних параметрів таймера

OnCalendar

Визначає, коли повинен спрацювати таймер, виходячи з календарного часу. Синтаксис є гнучким:

  • daily = --* 00:00:00
  • weekly = Mon --* 00:00:00
  • monthly = --01 00:00:00
  • yearly = *-01-01 00:00:00

Постійний

Якщо встановлено значення true, і система була вимкнена в момент, коли мав спрацювати таймер, він запуститься одразу після наступного завантаження.

OnBootSec / OnStartupSec

Запускає таймер після завантаження системи або запуску systemd.

OnUnitActiveSec / OnUnitInactiveSec

Тригери, пов’язані з моментом останньої активності або неактивності служби.

AccuracySec

Визначає діапазон точності для спрацьовування таймера (за замовчуванням: 1 хвилина). Цей параметр можна налаштувати з метою економії енергії:

AccuracySec=1h

Корисні команди для управління

# Переглянути всі таймери та час їхнього наступного спрацьовування
systemctl list-timers

# Перевірити стан конкретного таймера
systemctl status backup-script.timer

# Переглянути журнали обслуговування
journalctl -u backup-script.service

# Переглянути журнали з моменту останнього завантаження
journalctl -u backup-script.service -b

# Follow logs in real-time
journalctl -u backup-script.service -f

# Запустити службу таймера вручну
systemctl start backup-script.service

# Зупинити таймер
systemctl stop backup-script.timer

# Вимкнути запуск таймера під час завантаження
systemctl disable backup-script.timer

# Перевірити, коли спрацює таймер наступного разу
systemctl list-timers backup-script.timer

Таймери на рівні користувача

Для користувачів, що не мають прав суперкористувача, таймери можна розміщувати в каталозі ~/.config/systemd/user/ та керувати ними за допомогою прапора --user:

# Enable user timer
systemctl --user enable my-script.timer

# Start user timer
systemctl --user start my-script.timer

# List user timers
systemctl --user list-timers

# Enable lingering (allows user timers to run without login)
sudo loginctl enable-linger username

Приклад для досвідчених користувачів: сервіс із повідомленням електронною поштою

backup-with-notification.service:

[Unit]
Description=Backup with notification
OnFailure=failure-notification@%n.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
ExecStartPost=/usr/local/bin/notify-success.sh

Поради з налагодження

  • Перевірка синтаксису: скористайтеся командою systemd-analyze calendar «Mon *-*-* 09:00:00» для перевірки виразів OnCalendar

  • Пробний запуск: перед увімкненням таймера протестуйте службу вручну: sudo systemctl start backup-script.service

  • Детальне ведення журналу: додайте до файлу служби:

    [Service]
     StandardOutput=journal
     StandardError=journal
  • Перевірка точності таймера: systemctl show backup-script.timer -p NextElapseUSecRealtime

  • Перевірити, чи запущено таймер у користувацькому оточенні

    # Стан конкретного таймера
    systemctl --user status my-script.timer
    # Список усіх активних таймерів користувача
    systemctl --user list-timers --all
  • Перезапустити systemd після оновлення сервісу Після зміни файлів юнітів (служби чи таймера) треба повідомити systemd про оновлення:

    systemctl --user daemon-reload          # для користувацьких юнітів
    # або
    systemctl daemon-reload                 # для системних юнітів

Після цього можна (за потреби) перезапустити конкретний сервіс:

systemctl --user restart my-script.service   # користувацький
# або
systemctl restart my-service.service         # системний

Якщо змінили лише таймер, достатньо перезавантажити таймер:

systemctl --user restart my-script.timer

Тепер нові налаштування будуть застосовані без перезавантаження всієї системи.

Висновок

Таймери systemd є потужною, сучасною альтернативою cron із кращою інтеграцією, веденням журналів та гнучкістю. Хоча вони вимагають більше початкового налаштування, переваги в плані обслуговування, моніторингу та інтеграції в систему роблять їх вартими уваги для нових розгортань.

Для існуючих систем із діючими завданнями cron міграція може бути поступовою. Почніть із нових запланованих завдань, використовуючи таймери systemd, і з часом переносьте критичні завдання cron, коли ви краще ознайомитеся із синтаксисом та інструментами.