MAATRIX / Блог / Задержка скачет ровно раз в час: как поймать периодическую проблему в сети

Задержка скачет ровно раз в час: как поймать периодическую проблему в сети

MAATRIX

Мониторинг рисует пилу: задержка держится на ровном уровне, а потом раз — скачок, через час снова ровно, и снова скачок. Если приглядеться к меткам времени, скачки ложатся почти под линейку: 13:00, 14:00, 15:00, или каждые пять минут секунда в секунду. Это не случайный шум сети — это чужое расписание, которое пересекается с вашим трафиком. Разберём, почему регулярный период сам по себе — сильная диагностическая улика, какие классы причин за ним обычно стоят, и как найти конкретный виновника по логам и графику, а не гадая.

Почему регулярный период — это улика, а не просто узор

Случайная деградация сети — перегруз магистрального канала, чужой всплеск трафика на общем оборудовании провайдера, кратковременная проблема маршрутизации — почти никогда не выстраивается в идеально ровный интервал. У живого трафика нет метронома: пользователи заходят на сайт не по расписанию, всплески нагрузки от реальных людей размазаны во времени и зависят от часового пояса, дня недели, внешних событий. Если скачок происходит хаотично — раз в 20 минут, потом через 40, потом через 8 — это больше похоже на органическую перегрузку или проблему на магистрали.

А вот когда интервал между скачками воспроизводится с точностью до минуты (а иногда и до секунды) на протяжении многих циклов подряд — это почти всегда означает, что где-то в цепочке есть задача, запущенная по расписанию: cron на вашем сервере, systemd-таймер, планировщик приложения, служебный скрипт хостинг-провайдера или агент мониторинга. Расписания в Linux и в облачных платформах в подавляющем большинстве случаев привязаны к круглым отметкам времени — начало часа, каждые 5/10/15 минут, полночь по UTC — потому что так их проще администрировать и предсказывать. Именно эта «круглость» и выдаёт источник.

Полезно сразу отличать два похожих, но разных паттерна:

  • Жёсткая привязка к часам (ровно в HH:00, HH:15, HH:30, HH:45) — почти всегда классический cron-формат 0 * * * * или systemd OnCalendar=hourly. Круг подозреваемых сужается до задач, которые запускаются по системному времени.
  • Регулярный, но не привязанный к круглым меткам интервал (например, скачок ровно каждые 37 минут, но не в 0/15/30/45) — чаще указывает на таймер вида OnUnitActiveSec (отсчёт от момента предыдущего запуска, а не от круглой отметки) или на цикл внутри самого приложения (sleep(N) в воркере), а не на классический cron.

Оба случая диагностируются одинаково: сначала подтверждаем, что периодичность реальна и устойчива, а не совпадение на коротком отрезке наблюдения, а затем ищем, что именно просыпается в эти моменты.

Cron-задачи на самом сервере: первый подозреваемый

Прежде чем подозревать провайдера или соседей, стоит исчерпывающе проверить своё же расписание — в подавляющем большинстве случаев причина находится именно здесь. На сервере может быть несколько независимых источников периодических задач одновременно, и все их стоит собрать в один список:

# пользовательские crontab всех аккаунтов
for u in $(cut -f1 -d: /etc/passwd); do
  crontab -u "$u" -l 2>/dev/null | grep -v '^#' | sed "s/^/[$u] /"
done

# системные cron-каталоги
cat /etc/crontab
ls /etc/cron.d/
ls /etc/cron.hourly/ /etc/cron.daily/ /etc/cron.weekly/

# systemd-таймеры — современная замена cron во многих дистрибутивах
systemctl list-timers --all

Обратите внимание не только на явные бэкапы, но и на менее очевидные вещи: ротацию логов (logrotate, часто запускается из /etc/cron.daily или отдельным таймером), синхронизацию пакетов и репозиториев, обновление сертификатов (certbot renew по таймеру дважды в сутки), health-check скрипты, которые сами что-то шлют по сети. Если ротация логов настроена с пересылкой архива во внешнее хранилище или на сервер логирования — это тоже сетевая нагрузка по расписанию, и именно про конкуренцию фоновых задач с пользовательским трафиком за один канал подробно разобрано в статье про шейпинг и приоритизацию трафика на сервере.

Дальше сопоставляем расписание с точным временем скачков через системные логи:

# все события за конкретный час из journald
journalctl --since "2026-08-27 14:00:00" --until "2026-08-27 14:05:00"

# то же самое из классического syslog/cron-лога
grep "27 14:0" /var/log/syslog /var/log/cron 2>/dev/null

# конкретно старты cron-задач
grep CRON /var/log/syslog | grep " 14:0"

Если в этом же временном окне (с запасом в минуту-две до и после скачка — задача может стартовать чуть раньше, чем даст сетевой эффект) в логах появляется старт какой-то задачи — это первый кандидат. Дальше стоит временно отключить именно её (закомментировать строку в crontab, systemctl disable --now имя.timer) и понаблюдать один-два цикла: если периодичность скачков пропала вместе с задачей — причинно-следственная связь подтверждена, а не просто совпадение по времени.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Мониторинг и агенты: тяжёлый цикл сбора метрик

Второй частый источник — сам мониторинг, который призван отлавливать проблемы, а на деле их иногда создаёт. Лёгкие метрики (CPU, память, сетевые счётчики) агенты обычно собирают часто и почти бесплатно по нагрузке — раз в 10-15 секунд. Но у многих систем мониторинга есть отдельный, более тяжёлый цикл, который срабатывает заметно реже:

  • полное сканирование дискового пространства (du по всем каталогам) для дашборда использования диска;
  • полный список процессов с их метриками вместо агрегатов;
  • пересборка и отправка большого пакета телеметрии одним запросом раз в час вместо потокового стриминга;
  • health-check от внешнего сервиса аптайм-мониторинга с крупным телом запроса или проверкой сразу нескольких эндпоинтов подряд.

Такие циклы часто настроены с интервалом ровно 5, 15, 30 или 60 минут — потому что так удобнее визуально на графиках и проще объяснить в документации агента. Если у вас установлен zabbix-agent, netdata, node_exporter с дополнительными collector-скриптами, APM-агент (New Relic, Datadog и аналоги) или собственный скрипт, который раз в N минут собирает диагностику и отправляет её наружу — загляните в его конфиг на предмет интервалов, отличных от базового:

# пример: искать интервалы в конфиге агента мониторинга
grep -riE "interval|schedule|cron" /etc/zabbix/zabbix_agentd.conf
grep -riE "interval" /etc/netdata/netdata.conf

Отдельно стоит проверить исходящий трафик самого агента мониторинга — если он раз в час выгружает архив логов или полный дамп метрик на внешний сервер сбора, это создаёт кратковременный, но заметный всплеск на исходящем канале, который накладывается на пользовательский трафик точно так же, как и любой другой фоновый процесс.

Scheduled-задачи облачного провайдера

Третий класс причин — расписания, которые находятся не под вашим контролем вообще: их настраивает хостинг-провайдер на уровне гипервизора или платформы. Общая идея, без привязки к конкретному провайдеру и без гарантии, что у вас настроено именно так: облачные и VPS-платформы часто выполняют автоматические снапшоты дисков по расписанию, служебное обслуживание хост-машины, ротацию внутренних логов платформы или синхронизацию образов — и всё это может создавать кратковременную нагрузку на общий канал или на дисковую подсистему хоста, которая отражается на всех виртуалках этого физического сервера одновременно, а не только на вашей.

Отличить такую причину сложнее, потому что в ваших собственных логах не найдётся ни одной строчки — задача выполняется вне вашей виртуальной машины. Косвенные признаки:

  • скачок совпадает по времени у нескольких ваших серверов на одном провайдере, но в разных проектах и с разной нагрузкой;
  • в панели управления или в тикете поддержки хостер подтверждает окно обслуживания или расписание снапшотов;
  • эффект пропадает после миграции на другой физический хост (если провайдер это предлагает) при неизменном расписании ваших собственных задач.

Отдельная и практически неотличимая на первый взгляд история — периодическая задача не у провайдера, а у соседа по тому же физическому серверу: чужой бэкап, синхронизация или экспорт данных, который по расписанию забивает общий исходящий канал. Реальный разбор именно такого случая — с обнаружением скачка ровно в одно и то же время каждую ночь и выходом на бэкап соседней виртуалки — есть в статье «Скачки задержки ровно в 03:15: бэкап соседа забивал общий аплинк». Методика измерения того, сколько канала реально достаётся именно вам в конкретный момент времени, разобрана в статье про измерение своей доли сетевого канала на VPS — регулярные замеры полосы, сделанные именно в момент скачка, часто и есть недостающее доказательство.

Собственные scheduled-джобы приложения

Четвёртый источник — самый близкий к вам, но его почему-то проверяют в последнюю очередь: планировщик задач внутри самого приложения. Практически любой стек имеет свой механизм периодических job'ов, независимый от системного cron:

СтекГде искать расписание
Python / Celerycelery beat конфиг, CELERYBEAT_SCHEDULE
Ruby / Sidekiqsidekiq-cron, config/schedule.yml
PHP / Laravelapp/Console/Kernel.php, метод schedule()
Node.jsnode-cron, agenda, bull с повторяющимися job'ами
Kubernetesресурсы CronJob, kubectl get cronjobs -A

Типичные кандидаты внутри приложения: пакетная обработка очереди раз в N минут, генерация и отправка отчётов по расписанию, синхронизация с внешним API или платёжной системой, прогрев кэша, экспорт данных в аналитику, плановая архивация старых записей в БД. Каждая такая задача, если она делает сетевые запросы наружу (к внешнему API, в очередь сообщений, в объектное хранилище) или создаёт заметную нагрузку на диск и CPU, способна на секунды-десятки секунд просадить отзывчивость остального приложения на этом же сервере — и именно эта просадка видна снаружи как скачок задержки.

Проверяется это так же, как и системный cron: смотрим логи приложения на предмет старта job'а в нужную минуту, при возможности временно откладываем или переносим задачу и смотрим, исчез ли эффект. Полезная деталь: если у планировщика job'а есть настройка OnUnitActiveSec-подобного типа (отсчёт от предыдущего запуска, а не от круглой отметки времени), интервал между скачками будет регулярным, но не совпадать с круглыми часами — это отличает такие задачи от классического cron и сразу сужает поиск.

Метод локализации: время, логи и график за несколько дней, а не за час

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

1. Подтвердите, что периодичность реальна. Одного-двух совпадений недостаточно — совпадение может быть случайным. Соберите данные пинга или трассировки за несколько дней подряд (а не за час), с записью точных таймстампов каждого замера. Для этого подходит непрерывный mtr --report, smokeping или любой внешний мониторинг с логированием — принцип построения такого мониторинга из нескольких точек разобран в статье про мониторинг связности из десяти городов. На графике за несколько суток регулярный узор виден сразу глазами — ровные зубцы через одинаковый интервал, а не хаотичный разброс.

# непрерывный лог задержки с таймстампом каждой строки, на несколько суток
ping -D example.com | while read -r line; do
  echo "$(date '+%Y-%m-%d %H:%M:%S') $line"
done >> /var/log/latency-watch.log

2. Зафиксируйте точный интервал и его стабильность. Выпишите время каждого скачка из графика или лога и посчитайте разницу между соседними событиями. Если разница почти постоянна (например, всегда около часа с разбросом в пределах минуты) — это подтверждает scheduled-природу проблемы, а не просто повторяющуюся, но случайную по сути нагрузку.

3. Прогоните все источники расписаний за это конкретное окно. Одной командой удобно проверять сразу несколько журналов вокруг найденного времени:

WHEN="2026-08-27 14:0"
grep "$WHEN" /var/log/syslog /var/log/cron /var/log/auth.log 2>/dev/null
journalctl --since "2026-08-27 13:58:00" --until "2026-08-27 14:05:00"

Проверяйте не только системный cron, но и планировщик приложения, конфиги агента мониторинга и — если есть доступ — панель провайдера на предмет запланированных снапшотов или окон обслуживания.

4. Если внутри сервера ничего не совпало — смотрите наружу. Проверьте, не привязан ли скачок к соседям по хосту (см. выше про общий канал) и не подтверждает ли поддержка хостера служебное расписание. Здесь же стоит исключить встречный вариант: возможно, регулярность создаёт не чужая, а ваша же внешняя зависимость — например, партнёрский API или платёжный шлюз, к которому ваше приложение обращается по расписанию и который сам периодически подтормаживает на своей стороне.

5. Докажите причину, а не просто предположите её. Финальный и самый надёжный шаг — временно отключить, перенести на другое время или ограничить по скорости задачу-подозреваемого (через тот же traffic shaping, если совсем убрать её нельзя) и убедиться, что периодичность скачков исчезла или сдвинулась вместе с ней. Совпадение по времени — хорошая гипотеза, но именно эксперимент с отключением превращает её в подтверждённый диагноз.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

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

Скачок происходит не строго по часам, а плюс-минус пара минут каждый раз — это всё ещё расписание?

Да, разброс в одну-две минуты — это нормально для задач, которые в очереди ждут освобождения ресурса, или для таймеров с рандомизированной задержкой старта (в systemd есть RandomizedDelaySec специально для того, чтобы много задач не стартовали в одну и ту же секунду). Важна не идеальная точность до секунды, а устойчивость интервала на протяжении многих циклов.

Что делать, если ни одна из моих задач не совпадает по времени со скачком?

Расширьте окно поиска в логах на 3-5 минут в обе стороны — сетевой эффект от задачи может проявиться не в момент её старта, а чуть позже, когда она реально начинает передавать данные. Если и это не помогает, переходите к внешним причинам: соседям по хосту и служебным расписаниям провайдера.

Можно ли просто перенести подозрительную задачу на непиковое время, не разбираясь до конца в причине?

Можно и часто это самое практичное решение для собственных задач — сдвинуть бэкап или отчёт на ночные часы с низкой пользовательской нагрузкой снимает симптом. Но если периодичность создаёт не ваша задача, а сосед по хосту или сам провайдер, перенос собственного расписания ничего не даст — сначала нужно всё-таки локализовать источник.

Помогает ли просто увеличить канал или мощность сервера, если проблема периодическая?

Иногда снимает симптом, но не устраняет причину: если периодичность создаёт конкретная задача, которая на секунды выедает весь канал или диск, больший запас ресурсов действительно может скрыть эффект. Но это дороже и менее предсказуемо, чем один раз найти и либо ограничить, либо перенести саму задачу.

Стоит ли сразу писать в поддержку хостера, если подозреваю служебное расписание на их стороне?

Стоит, но с доказательствами на руках: точные таймстампы скачков за несколько суток, подтверждение, что на вашей стороне в это время ничего не запускается, и (если есть) данные о доле канала, которая вам реально доступна в момент скачка. Тикет с конкретным графиком и временными метками разбирается быстрее, чем сообщение «у меня иногда тормозит».

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →