MAATRIX / Блог / Попали в крупную подборку: трафик вырос в двадцать раз за ночь — что делать в моменте

Попали в крупную подборку: трафик вырос в двадцать раз за ночь — что делать в моменте

MAATRIX

Утро, телефон разрывается от уведомлений мониторинга, а в панели хостинга график нагрузки выглядит как вертикальная стена. Кто-то опубликовал ссылку на ваш проект в крупном СМИ, популярном телеграм-канале или подборке вроде «10 сервисов, которые нужно попробовать» — и трафик, который вчера измерялся сотнями визитов, сегодня измеряется десятками тысяч. Хорошая новость сгорает в тревоге: сервер не тянет, страницы отдаются через раз, часть пользователей просто не долистывает до вашего контента. Дальше — конкретный план действий на первые 30-60 минут, без попыток «переписать всё правильно» посреди пожара.

Первым делом: не гадать, а измерить

Главная ошибка первых минут — начать чинить наугад: перезапускать сервисы, увеличивать лимиты вслепую, чистить кеш «на всякий случай». Каждое такое действие занимает время и может усугубить ситуацию, если бьёт не в ту точку. Сначала — 3-5 минут на диагностику, чтобы понять, где именно узкое место.

Быстрый чек-лист по подсистемам:

uptime                      # load average — если сильно больше числа ядер, узкое место CPU
free -h                     # свободная память и swap — если swap растёт, это тревожный знак
vmstat 1 5                  # столбец wa — доля времени в ожидании диска
iostat -xz 1 5              # %util по дискам — близко к 100% = диск упёрся
ss -s                       # общее число соединений и их состояния
ss -tan state established | wc -l   # сколько реально держится открытых соединений
dmesg -T | grep -i "killed process"  # не убивал ли OOM-killer процессы по памяти

Практическая логика: load average в разы выше числа ядер при низком wa — упор в CPU. wa растёт, %util в iostat под 100% — упор в диск (частый виновник — логи или временные файлы). Свободная память тает, swap растёт — упор в память, дальше ищите процесс через ps aux --sort=-%mem | head. Если CPU и память в порядке, а сайт всё равно тормозит — вероятно, дело в очереди соединений или в базе: для MySQL это SHOW FULL PROCESSLIST;, для PostgreSQL — SELECT * FROM pg_stat_activity WHERE state != 'idle';.

Отдельно проверьте веб-сервер: curl localhost/nginx_status (если включён stub_status) покажет число активных соединений и очередь на приём. Для PHP-FPM полезно заглянуть в лог — если там пошли строки вида server reached max_children, значит пул воркеров упёрся в лимит раньше, чем в CPU или память, и решение — в конфиге, а не в апгрейде сервера.

Если у вас уже настроен мониторинг с историей метрик — не тратьте время на команды вручную, сразу открывайте дашборд: там узкое место видно за секунды, а не за пять минут набора команд. Про то, как строится такой мониторинг заранее, — в статье про мониторинг связности из нескольких городов: она о другом сценарии (проверка доступности извне), но принцип тот же — метрики должны быть готовы до того, как они понадобятся в панике. Отдельная ловушка на этом этапе: health-check может показывать «зелёный» статус, а пользователи всё равно жаловаться на тормоза — разбор такого случая объясняет, почему поверхностная проверка врёт именно тогда, когда нужна больше всего.

Пожарные меры: кеш и отключение лишнего

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

Кеш на полную мощность. Если у вас уже стоит nginx с proxy_cache или fastcgi_cache, но TTL настроен консервативно (30-60 секунд) — на время пика это можно поднять до нескольких минут. Да, часть пользователей увидит чуть устаревшую версию страницы — это разумный компромисс против полной недоступности. Ключевая директива, которая спасает именно в момент скачка нагрузки:

proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
proxy_cache_valid 200 5m;

proxy_cache_use_stale updating означает: пока кеш обновляется в фоне, отдавать старую версию, а не заставлять пользователя ждать бэкенд. Это резко снижает нагрузку на приложение и базу — сотни одновременных запросов на одну страницу перестают долбить бэкенд параллельно (эффект cache stampede, если пустить его на самотёк).

Если у вас WordPress или похожая CMS — проверьте, включён ли плагин кеширования страниц (не только кеш объектов) и не выключен ли он случайно после последнего обновления. Если статических файлов много — временно агрессивно закешируйте их на CDN или edge-прокси с большим TTL, даже если обычно вы кешируете аккуратнее.

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

  • клиентские и серверные счётчики аналитики (Google Analytics, Яндекс.Метрика, собственные event-трекеры) — они добавляют лишние запросы и JS-нагрузку, а в моменте пиковый трафик важнее точной аналитики за этот час;
  • фоновые задачи и воркеры очередей, которые конкурируют за CPU и соединения к базе с веб-процессом — временно останавливаете или уменьшаете параллелизм (systemctl stop myapp-worker или снижение числа воркеров Sidekiq/Celery до минимума);
  • пересчёт рекомендаций, «похожих товаров», live-счётчиков комментариев на лету — замените на статичный или закешированный вариант;
  • ресайз изображений на лету — если у вас есть заранее сгенерированные превью, отдавайте их, а обработчик «на лету» временно отключите;
  • индексацию поиском, переиндексацию каталога, любые cron-задачи обслуживания, которые не обязаны выполниться именно сейчас.

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

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

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

Экстренно нарастить VPS

Экстренный вертикальный апгрейд: что реально «на лету»

Если пожарные меры сняли часть нагрузки, но её всё равно больше, чем сервер способен переварить, следующий шаг — вертикальный апгрейд: больше vCPU, больше RAM, иногда быстрее диск. У большинства VPS-провайдеров это делается за минуты через панель управления или API, без переустановки системы.

Важно понимать реальные ограничения такого апгрейда, чтобы не терять время на ложных ожиданиях:

  • Изменение CPU и RAM почти всегда требует перезагрузки виртуальной машины. «Горячее» добавление ресурсов без даунтайма поддерживают немногие платформы — закладывайтесь на выключение и включение, обычно порядка минуты простоя, а не часы. Уточните у провайдера заранее, поддерживает ли тариф resize без полной переустановки — обычно это отдельная опция в панели.
  • Расширение диска чаще можно сделать «на лету», особенно на LVM или ZFS — расширение раздела и файловой системы выполняется без остановки сервиса, но требует аккуратности с порядком действий.
  • Смена тарифного плана целиком (другая линейка процессоров, другой класс диска) обычно не мгновенна — это фактически миграция на новый инстанс, и в моменте кризиса на неё нет времени. Если нужно радикально больше мощности прямо сейчас — проще временно поднять параллельно ещё один сервер под часть трафика, чем ждать миграции основного.

Прежде чем жать «апгрейд» — вернитесь к диагностике из первого раздела. Апгрейд CPU не поможет, если узкое место — упор в диск или в лимит соединений к базе данных; вы потратите деньги и время простоя на перезагрузку, а картина не изменится. Это частая и обидная ошибка — масштабировать раньше, чем найдено настоящее узкое место обходится дороже, чем лишние три минуты диагностики.

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

Если апгрейд не успевает: осознанное ограничение вместо падения

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

Практические варианты graceful degradation:

Лимитирование запросов на входе. В nginx это limit_req с очередью (burst) и явным ответом на превышение:

limit_req_zone $binary_remote_addr zone=main:10m rate=10r/s;

location / {
    limit_req zone=main burst=20 nodelay;
    limit_req_status 503;
}

error_page 503 /high-load.html;

Превысившие лимит получают не зависший таймаут, а быстрый и понятный ответ — статическую страницу «сейчас высокая нагрузка, обновите через минуту» с заголовком Retry-After. Это честнее по отношению к пользователю, чем 30 секунд ожидания и обрыв соединения.

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

Статическая «заглушка» вместо динамики. Если конкретная страница стала точкой притяжения трафика, а генерируется она динамически и дорого — сгенерируйте её один раз вручную и отдавайте как статический файл через nginx try_files, минуя бэкенд и базу целиком. Грубо, зато полностью снимает нагрузку с самого дорогого места.

Managed-опции провайдеров. Если сайт стоит за CDN или прокси-провайдером, у многих есть встроенный режим повышенной защиты (агрессивный челлендж ботам, временное ужесточение rate limiting на грани). Это быстрее, чем настраивать всё вручную на своём сервере, и стоит включить в первую очередь, если такая опция уже подключена.

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

Чего не делать в моменте

Соблазн в разгар инцидента — начать чинить «правильно»: переписать медленный запрос, вынести кеш в отдельный Redis, перейти на очередь сообщений, добавить реплику базы. Все эти решения могут быть абсолютно верными — но не сейчас. Архитектурные изменения посреди пожара почти всегда занимают больше времени, чем кажется, требуют тестирования и рискуют внести новую ошибку именно тогда, когда система и так на пределе.

Правило простое: сначала стабилизация доступными средствами — диагностика, кеш, отключение лишнего, вертикальный апгрейд, ограничение трафика. Архитектурные выводы — после того, как всплеск прошёл и у вас снова есть время думать, а не тушить. То же самое правило действует и в других видах инцидентов: подробный пошаговый регламент первых минут разбора (не про трафик, а про инциденты в целом) описан в статье про первые 15 минут инцидента — стоит прочитать заранее, а не в момент, когда график уже летит вверх.

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

Чек-лист первых 60 минут

Ориентировочная последовательность, если трафик уже растёт и сервер испытывает нагрузку прямо сейчас:

ВремяДействие
0-5 минДиагностика: load average, память, диск, соединения, состояние БД — найти узкое место, не гадать
5-15 минУсилить кеш (TTL, proxy_cache_use_stale), отключить аналитику и фоновые задачи, некритичные тяжёлые функции
15-25 минЕсли не хватило — вертикальный апгрейд CPU/RAM через панель провайдера (закладывайте минуту простоя на перезагрузку)
25-35 минПока апгрейд применяется — включить лимитирование запросов и/или статическую заглушку на самой нагруженной странице
35-60 минОценка: нагрузка стабилизировалась? Если да — постепенно возвращать отключённые функции, если нет — искать следующее узкое место по тому же циклу

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

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

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

Экстренно нарастить VPS

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

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

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

Сколько времени есть до того, как большинство посетителей уйдёт из-за медленной загрузки?

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

Стоит ли сразу выключить сайт, чтобы не упасть совсем под неконтролируемой нагрузкой?

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

Можно ли увеличить лимиты nginx или PHP-FPM без перезапуска всего сервиса?

Для nginx — да, nginx -s reload применяет новый конфиг без разрыва существующих соединений. Для PHP-FPM изменение pm.max_children требует перезапуска пула (systemctl reload php8.3-fpm в современных версиях справляется мягко, но проверьте конкретно для вашей версии — где-то нужен именно restart).

Что делать, если узкое место — база данных, а не сам сервер приложения?

Первым делом смотрите на активные и заблокированные запросы (SHOW FULL PROCESSLIST / pg_stat_activity) — часто один медленный запрос или отсутствующий индекс держит остальные в очереди. В моменте кризиса можно временно завершить самые долгие некритичные запросы (KILL <id> в MySQL, pg_terminate_backend() в PostgreSQL), отключить фоновые задачи, которые тоже бьют в базу, и полагаться на кеш страниц, чтобы часть запросов вообще не доходила до БД. Добавление индекса или реплики — это уже работа после инцидента, не во время него.

Нужно ли после всплеска что-то менять в архитектуре?

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

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

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

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