Блог
VPS · практикаVPS и хостинг 7 мин чтения

Cron vs systemd timers на VPS: что выбрать в 2026

Cron остаётся стандартом, но systemd timers дают лучше логирование, зависимости и мониторинг. Разбираем разницу, migration-путь и минимальные шаблоны.

Плановые задачи — самая недооценённая часть операционной работы. Бэкапы, ротация логов, cleanup, синхронизация — всё это или cron, или systemd timers. Правильный выбор экономит часы поиска «почему не запускается» через полгода.

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

Cron — классика с известными проблемами

Cron — стандарт с 70-х. Работает везде, синтаксис знакомый: 5 3 * * * /usr/local/bin/backup.sh.

Проблемы cron в 2026:

  • PATH и env не как у обычного пользователя — скрипт может работать из shell, но падать из cron из-за отсутствия $PATH.
  • Логирование в /var/log/syslog только сам факт запуска. stdout/stderr скрипта уходит в письмо root@localhost, которое обычно никто не читает.
  • Нет зависимостей — нельзя сказать «запусти после NetworkManager» или «только если mysql жив».
  • Нет retries при провале.
  • Overlap — если предыдущий запуск не завершился, следующий запустится тоже, и они начнут конфликтовать.
  • Учёт пропущенных запусков — если сервер был выключен на время cron-задачи, она просто не выполнится.

Systemd timers — современная альтернатива

Systemd timers решают почти все проблемы cron ценой некоторой verbose-ности конфигурации. Есть на всех дистрибутивах с systemd (Ubuntu 16.04+, Debian 8+, CentOS 7+).

Плюсы:

  • Логи в journaldjournalctl -u mytask.service покажет весь stdout/stderr.
  • ЗависимостиAfter=network.target mysql.service гарантирует порядок.
  • PersistentPersistent=true запустит задачу, если пропущен запуск (после выключения).
  • Anti-overlap — по умолчанию, service не запустится дважды, если предыдущий не завершился.
  • Мониторинг — status service показывает: активен, когда последний запуск, когда следующий.
  • RandomizationRandomizedDelaySec рассеивает нагрузку от одинаковых задач на нескольких серверах.

Практика: cron

Пример backup-cron с типовыми предосторожностями:

# /etc/cron.d/backup — редактируется прямо в файле
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
[email protected]

# Backup каждый день в 3:15 ночи
15 3 * * * root flock -n /var/lock/backup.lock /usr/local/bin/backup.sh >>/var/log/backup.log 2>&1

# flock -n не даст запуститься второму экземпляру
# 2>&1 в log — иначе всё уходит в почту root

Практика: systemd timer

Тот же backup через systemd — два файла:

# /etc/systemd/system/backup.service
[Unit]
Description=Nightly backup
After=network-online.target mysql.service
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=backup
StandardOutput=journal
StandardError=journal
Environment="AWS_ACCESS_KEY_ID=..." "AWS_SECRET_ACCESS_KEY=..."

# /etc/systemd/system/backup.timer
[Unit]
Description=Nightly backup timer

[Timer]
OnCalendar=daily
AccuracySec=1min
RandomizedDelaySec=15min
Persistent=true

[Install]
WantedBy=timers.target

# Активация:
systemctl daemon-reload
systemctl enable --now backup.timer
systemctl list-timers

Когда что использовать

Cron — если:

  • Задача простая (сдёрнуть логи, ротация).
  • Проект использует несколько дистрибутивов (в т.ч. BSD/Alpine — там нет systemd).
  • Команда привыкла к cron.
Systemd timers — если:
✅ Нужна нормальная логика (retry, dependencies, logs)
✅ VPS иногда выключается — важен Persistent
✅ Много одинаковых серверов — RandomizedDelaySec
✅ Мониторинг: journalctl + Prometheus systemd_exporter

Совет по надёжности

Что бы вы не выбрали:

  • Логируйте всё — stdout+stderr в файл или journald.
  • Мониторьте — не полагайтесь только на «раз в день». Уведомляйте через Healthchecks.io: скрипт пингует URL при успехе, healthchecks шлёт alert, если пинг пропущен.
  • Не пишите бизнес-логику в скрипте на 500 строк — вынесите в отдельный package.
  • Timeout — обязательный (timeout 3600 ./backup.sh) — иначе застрявший процесс будет висеть неделями.
Совет

Healthchecks.io free-план поддерживает 20 checks — достаточно для среднего проекта. Отправляйте curl из скрипта при успехе, получайте alert при отсутствии пинга.

Частые вопросы

Cron ещё жив в 2026?
Да, стандарт для простых задач. На новых системах — часто systemd timers по умолчанию для системных задач (logrotate, apt-daily).
Как посмотреть, что запланировано?
Cron: `crontab -l`, `ls /etc/cron.*`. Systemd: `systemctl list-timers --all`.
Что делать с overlapping задачами?
Cron: обернуть в `flock -n`. Systemd: обычное поведение — не даст запуститься второму экземпляру.
Timezone у cron/systemd?
Cron: локальный timezone сервера. Systemd: можно `OnCalendar=daily UTC` — явно указать.