Верстакфорум практиков
рекламаiprazon: приватные серверные адреса IPv4 и SOCKS5, безлимитный трафик, бесплатный тест до 2 часов
ФорумСкрипты и автоматизация

cron и часовые пояса: прогон уехал на час

cronjob
cronjob
Новичок
сообщений 205
с фев, второй сезон
15 марта, 14:02первое сообщение

Ночной прогон восемь месяцев стартовал в 03:00 по Москве. На выходных уехал: в логе старт 02:00, выгрузка легла на час раньше срока.

Сервер арендованный, crontab свой, руками никто ничего не трогал. Куда вообще смотреть?

iron_shell
iron_shell
Знаток
сообщений 1050
с июн
22 августа, 17:19#2

Смотреть надо в две разные вещи: часовой пояс системы и часовой пояс, в котором cron читает расписание. Вторая наследуется от первой ровно до того момента, пока ты её явно не задал.

что видит система и что видит cron
что видит система и что видит cron

Если у тебя записано 0 3 * * *, а система живёт в UTC, задание пойдёт в три по UTC. Пока пояс никто не менял, оно совпадало с привычным временем случайно. Сдвиг ровно на час говорит, что привязка к поясу где-то поменялась, чаще всего внутри образа системы после обновления.

cronjob
cronjob
Новичок
сообщений 205
с фев, второй сезон
1 января, 08:36#3
iron_shell: привязка к поясу где-то поменялась

Так и вышло. Хостер обновил образ, пояс контейнера переехал с Europe/Moscow на UTC. Записи в crontab остались прежними.

Дарья Смолина
Дарья Смолина
Участник
сообщений 340
с дек
8 июня, 11:53#4

Лечится одной строкой в начале crontab, если у тебя cronie или vixie-cron:

CRON_TZ=Europe/Moscow
0 3 * * * /opt/progon/run.sh

На busybox-кроне такой переменной нет, там придётся считать смещение руками и помнить о нём при каждой правке.

Максим Юрьев
Максим Юрьев
Знаток
сообщений 1720
с апр
15 ноября, 14:10#5

Я от привязки расписания к поясу с сезонным переводом стрелок ушёл совсем, и вот из-за чего.

Такой пояс даёт две дырки в году. В ночь, когда стрелки идут вперёд, часа 02:00 просто не существует, и задание, назначенное на это время, пропускается молча. В ночь, когда стрелки идут назад, час 02:00 случается дважды, и задание отрабатывает два раза подряд. Для сбора данных второе неприятнее первого: выгрузка дублируется, а потом кто-то полдня ищет, откуда взялись двойные строки.

Держу все расписания в UTC, человеческое время пересчитываю только при показе. Заодно перешёл на таймеры systemd, там есть догон пропущенного запуска:

[Unit]
Description=nochnoy progon

[Timer] OnCalendar=*-*-* 03:00:00 UTC Persistent=true RandomizedDelaySec=180 AccuracySec=1s

[Install] WantedBy=timers.target ```

Persistent=true догоняет запуск, если машина в это время лежала. RandomizedDelaySec разводит старты, когда таких заданий на машине десяток и все просыпаются в один момент.

cronjob
cronjob
Новичок
сообщений 205
с фев, второй сезон
22 апреля, 17:27#6

Поставил CRON_TZ, прогон вернулся на место: сегодня старт в 03:00 по Москве, выгрузка вовремя.

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