Распродажа началась в полночь: первые 15 минут решают всё
Обратный отсчёт на баннере доходит до нуля, тысячи человек одновременно обновляют страницу или уже сидят с открытой корзиной — и за следующие пятнадцать минут решается, соберёте вы кассу распродажи или потратите вечер на перезапуск сервисов под аккомпанемент жалоб в поддержку. В отличие от обычной аварии, этот скачок нагрузки не случайность: вы знаете точное время старта с точностью до секунды. Вопрос не в том, будет ли пик — а в том, готовы вы к нему заранее или будете реагировать по ходу дела.
Содержание
- Чем старт распродажи отличается от обычного инцидента
- Что рвётся первым, когда нагрузка растёт в разы за минуту
- Панель на экране: что смотреть с 23:55 и дальше
- Очереди и 5xx: как отличить симптом от причины
- Заранее заготовленные кнопки: что должно быть готово до полуночи
- Кто должен сидеть у монитора в момент старта
Чем старт распродажи отличается от обычного инцидента
Есть отдельный регламент на первые 15 минут любого инцидента — кого оповещать, как вести таймлайн, когда писать пользователям. Он универсален и подходит для любой аварии: сайт лёг ночью без видимой причины, сломался деплой, отвалился провайдер. Этот текст — про другое: про ситуацию, где авария не внезапна, а запланирована вами же. Вы точно знаете, когда включится баннер, когда откроется корзина по акционной цене и когда десятки тысяч человек одновременно нажмут «обновить». Это не сценарий «диагностировать неизвестную проблему», а сценарий «пережить известную нагрузку с минимальными потерями» — и работа с ним начинается не в полночь, а за дни до неё.
Разница принципиальная. В обычном инциденте первые минуты уходят на то, чтобы понять масштаб и причину. При старте распродажи причина известна заранее — это ваш собственный трафик, а не чья-то авария. Значит, всю диагностическую часть можно вынести за скобки и подготовить заранее: не гадать в моменте, что смотреть, а иметь открытую панель с нужными графиками ещё до полуночи, и не изобретать действия под давлением, а нажимать заранее подготовленные и один раз протестированные кнопки.
Второе отличие — у вас есть точная временная точка отсчёта. Скачок трафика на распродаже почти всегда имеет форму резкого пика в первые 5-15 минут с постепенным спадом после — если инфраструктура пережила именно этот пик, дальше обычно становится легче, а не тяжелее.
Что рвётся первым, когда нагрузка растёт в разы за минуту
Плавный рост нагрузки за часы система обычно переживает без проблем — успевает сработать автомасштабирование, прогреться кэш, стабилизироваться пул соединений к базе. Скачок за 60-120 секунд — совсем другая история: система не успевает адаптироваться, она либо держит удар с текущими ресурсами, либо начинает деградировать по цепочке.
Типичный порядок деградации выглядит так:
- Пул соединений к базе данных исчерпывается первым. Каждый новый запрос от нового посетителя открывает соединение (или ждёт его из пула). Если лимит подключений PostgreSQL или MySQL достигнут раньше, чем успело среагировать масштабирование, новые запросы начинают ждать или получать отказ — а это самое узкое место почти любой архитектуры.
- Очередь запросов на веб-сервере растёт. Пока приложение ждёт ответа от базы дольше обычного, воркеры nginx/приложения не освобождаются вовремя, и новые запросы копятся в очереди — вплоть до переполнения backlog.
- Время ответа растёт, клиенты начинают повторять запросы. Пользователь, который не дождался ответа за пару секунд, обновляет страницу или повторно жмёт «Оформить заказ» — это удваивает и утраивает реальную нагрузку сверх органического всплеска.
- Появляются 5xx. Сервис начинает явно отказывать: 502/504 от прокси, если бэкенд не успевает ответить, 503, если сработал лимит подключений или защита от перегрузки.
Прочитать эту цепочку в реальном времени — единственный способ понять, где именно рвётся именно ваша система, а не абстрактная. У кого-то первым сдаётся Redis, если через него идёт хранение сессий и корзин, у кого-то — очередь фоновых задач для отправки писем о заказе, у кого-то нагрузка вообще не доходит до базы, потому что раньше падает сама сеть на входе. Автомасштабирование, которое масштабирует счёт — отдельная тема, но здесь важно другое: автомасштабирование, рассчитанное на постепенный рост, часто не успевает среагировать за минуту-две резкого скачка — новый инстанс поднимается быстрее, чем полностью прогревается и начинает принимать полноценную нагрузку.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверПанель на экране: что смотреть с 23:55 и дальше
К моменту старта распродажи дашборд должен быть уже открыт — не «сейчас быстро зайду в Grafana и найду нужный график», а развёрнут на экране заранее, с обновлением раз в 5-10 секунд. Минимальный набор панелей:
- Загрузка БД: число активных подключений против лимита, наличие долгих запросов, репликационная задержка, если читающие запросы идут с реплики.
- Очереди приложения: глубина очереди воркеров (Sidekiq, Celery, встроенная очередь фреймворка), время ожидания в очереди, число одновременно обрабатываемых запросов против максимума.
- Ответы веб-сервера: доля 2xx/4xx/5xx в реальном времени, перцентили времени ответа (p50/p95/p99 — именно p95 и p99 покажут проблему раньше среднего значения).
- Ресурсы серверов: CPU, память, сеть — на каждом узле, а не только агрегированно, чтобы увидеть перекос нагрузки на один инстанс.
- Очередь на прокси/балансировщике: активные соединения, отклонённые соединения, если у балансировщика есть лимит.
Быстрые команды, которые полезно держать под рукой прямо на сервере, если полноценного дашборда нет или он молчит:
# активные подключения к PostgreSQL и что они делают
psql -c "SELECT count(*), state FROM pg_stat_activity GROUP BY state;"
# состояние очереди nginx (если включён stub_status/vhost_traffic_status)
curl -s http://127.0.0.1/nginx_status
# коды ответов за последнюю минуту прямо из access-лога
tail -n 5000 /var/log/nginx/access.log | awk '{print $9}' | sort | uniq -c | sort -rn
Важное правило этого пункта: не смотрите один график. Изолированный рост CPU на 80% ничего не говорит о том, есть ли реальная проблема — на CPU 80% сервис может прекрасно отвечать за 50 мс, а может уже сыпать таймаутами. Симптом становится сигналом только в связке: CPU растёт вместе с ростом времени ответа и появлением 5xx — вот тогда пора действовать, а не раньше.
Очереди и 5xx: как отличить симптом от причины
Самая частая ошибка первых минут — реагировать на симптом вместо причины. Рост 502/504 сам по себе не говорит, что чинить: это может быть перегруженный бэкенд, упавший воркер приложения, исчерпанный пул к базе или закончившиеся файловые дескрипторы на прокси. Что такое backlog соединений и почему клиент получает отказ на живом сервере — если backlog у веб-сервера или балансировщика мал, а очередь новых подключений переполняется быстрее, чем сервер успевает их принять, клиент получает отказ ещё до того, как запрос дошёл до приложения. Это выглядит как «сайт не открывается», хотя приложение внутри может быть живым и недогруженным.
Практический порядок диагностики по симптомам:
| Симптом | Куда смотреть | Частая причина в момент скачка трафика |
|---|---|---|
| 502 Bad Gateway | Логи и статус бэкенд-процессов | Приложение упало или не успевает поднять достаточно воркеров |
| 504 Gateway Timeout | Время ответа приложения, состояние БД | Приложение отвечает, но слишком медленно — часто из-за очереди к базе |
| 503 Service Unavailable | Лимиты прокси, rate-limit, health-check | Сработала защита от перегрузки или health-check счёл узел нездоровым |
| Растёт время ответа, кодов ошибок ещё нет | Очередь воркеров, пул подключений к БД | Система ещё держится, но уже на пределе — момент для превентивных действий |
| Ошибки только на конкретных страницах (оформление заказа, оплата) | Логи именно этого сервиса, а не общие | Узкое место не во входном трафике, а в конкретной цепочке (платёжный шлюз, склад) |
Последняя строка таблицы — частая ловушка при распродажах: главная страница и каталог держатся нормально, потому что закэшированы, а страница оформления заказа падает первой, потому что именно она бьёт напрямую в базу и во внешние сервисы (проверка остатков, платёжный провайдер). Если мониторить только общий процент ошибок по сайту, эту деградацию легко пропустить — она размывается в общей массе успешных запросов к статике и кэшированным страницам.
Заранее заготовленные кнопки: что должно быть готово до полуночи
Ключевая идея этого раздела — ни одно из перечисленных действий нельзя придумывать в моменте. Каждое должно быть написано, протестировано на стейджинге и один раз пройдено «руками» ещё до дня Х. В момент скачка трафика не время читать документацию к своему же feature-flag сервису.
Отключение необязательных фич. Заранее определите список того, что можно временно выключить без ущерба для оформления заказа: рекомендации «похожие товары», персонализированные баннеры, полнотекстовый поиск с подсветкой, история просмотров, отправка part-time аналитики на клиент. Технически это может быть флаг в конфиге, переменная окружения или сервис фича-флагов — важно, чтобы переключение занимало секунды, а не требовало деплоя:
# пример: флаг в .env, который читает приложение при каждом запросе
# (не при старте процесса — иначе понадобится перезапуск)
FEATURE_RECOMMENDATIONS=false
FEATURE_LIVE_SEARCH=false
FEATURE_REALTIME_STOCK_COUNTER=false
Статические страницы-заглушки для некритичных разделов. Если каталог с фильтрами создаёт основную нагрузку на базу, а сама распродажа держится на десятке акционных товаров — заранее подготовьте статический (полностью закэшированный или вообще сгенерированный заранее HTML) вариант страниц этих товаров и переключите на него трафик через nginx на время пика:
# в конфиге nginx: при активном флаге отдаём статическую версию
# каталога вместо динамической, если он существует
location /catalog/ {
if (-f /var/www/static_fallback$uri.html) {
rewrite ^ /static_fallback$uri.html break;
}
proxy_pass http://app_backend;
}
Это не заглушка «сайт на технических работах» — страница остаётся живой и продающей, просто не бьёт лишний раз в приложение и базу там, где это не обязательно.
Прогрев кэша до старта, а не после. Если ключевые страницы кэшируются (Redis, Varnish, кэш на уровне CDN), прогрейте их вручную за несколько минут до начала — первый посетитель не должен быть тем, кто своим запросом заполняет холодный кэш под нагрузкой в тысячи параллельных запросов. Эффект «стада», когда кэш только что протух и все параллельные запросы одновременно идут в базу — отдельная и очень частая причина падения именно в момент пика.
Масштабирование — заранее, а не по факту метрик. Автомасштабирование по нагрузке хорошо работает для органического роста в течение часов, но почти всегда опаздывает на резком скачке: пока метрика превысила порог, пока сработал алерт, пока поднялся и прогрелся новый инстанс — проходит больше времени, чем длится сам пик. Практичнее увеличить число работающих инстансов вручную (или поднять минимальный порог автомасштабирования) за 20-30 минут до старта, не полагаясь на реакцию системы постфактум. Это стоит денег даже если пик окажется меньше ожидаемого — но дешевле, чем потерянные заказы в первые минуты.
Отдельный пул подключений к базе с запасом. Если приложение использует PgBouncer или аналогичный пулер, заранее проверьте, что лимит пула рассчитан на пиковую нагрузку, а не на среднюю. Полезно держать под рукой команду для быстрой проверки состояния пулов прямо в момент пика:
# PgBouncer: состояние пулов и очередей ожидания
psql -p 6432 pgbouncer -c "SHOW POOLS;"
Если очередь ожидания (cl_waiting) начинает расти — это ранний сигнал, что приложению не хватает соединений раньше, чем это будет видно по общей нагрузке на сервер.
Кто должен сидеть у монитора в момент старта
Список ролей на время пика короче, чем полный список команды, но каждая роль должна быть закрыта конкретным именем, а не «кто-нибудь подключится по необходимости».
- Инженер у панели метрик. Смотрит на дашборд и озвучивает изменения вслух: «время ответа растёт», «пул к базе на 90%», «пошли 502 на checkout». Не чинит сам, даёт остальным актуальную картину.
- Инженер с правами на инфраструктуру. Может немедленно поднять инстансы, переключить фича-флаг, включить статическую заглушку — без согласований. Права выданы заранее, а не запрошены в момент пика.
- Ответственный за базу данных. Отдельный человек, который знает, как быстро посмотреть
pg_stat_activity, прибить зависший запрос, при необходимости временно поднять лимит подключений. - Тот, кто принимает решение об отключении фич. Решение «выключаем рекомендации прямо сейчас» — управленческое, а не только техническое: оно может задеть маркетинговые метрики. У него должен быть один явный владелец, а не консенсус впопыхах.
- Поддержка на усиленном режиме. Поток обращений «не могу оформить заказ» растёт кратно, и если поддержка узнаёт о проблеме от клиентов раньше, чем от команды, доверие теряется быстрее, чем чинится сама проблема.
Дежурство и эскалация в команде из трёх человек разбирает, как выстроить эти роли, если людей физически мало — специфика распродажи в том, что дежурство здесь не круглосуточное «на всякий случай», а точечное, спланированное под конкретный час. Если распродажа стартует в полночь, все перечисленные роли должны быть на связи именно в полночь, а не «доступны по звонку» — секунды на то, чтобы разбудить человека и ввести его в курс, в моменте стоят слишком дорого.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Стоит ли включать статические заглушки заранее, или только по факту проблем?
Для страниц, которые точно не изменятся в момент пика (каталог без персонализации, товары с фиксированной ценой), их разумно включить заранее — это снижает нагрузку с первой секунды, а не с момента, когда проблему заметят на дашборде.
Автомасштабирование настроено — обязательно ли всё равно масштабироваться вручную заранее?
Да, если пик резкий. Между превышением порога и полной готовностью нового инстанса проходит время, которого на резком скачке может не остаться. Ручное увеличение перед стартом — компенсация задержки реакции, а не недоверие к автомасштабированию.
Что делать, если 5xx уже пошли, а причина неочевидна?
Смотреть по таблице симптомов выше: где именно рвётся — на входе, в приложении или в базе. Включать заготовленные кнопки по одной, с фиксацией времени и эффекта, а не все сразу — иначе непонятно, что именно помогло.
Чем это отличается от обычного нагрузочного тестирования перед запуском?
Тестирование проверяет, выдержит ли система расчётную нагрузку в принципе, до дня Х. Этот текст — про сам момент пика, если тестирование не проводилось или трафик оказался острее прогноза. В идеале нужно и то, и другое.
Нужно ли всё это небольшому магазину с несколькими сотнями посетителей в пик?
В уменьшенном виде — да. Резкий скачок в 10-20 раз способен исчерпать небольшой пул подключений к базе или маленький backlog веб-сервера так же легко, как и у крупного магазина — меняется только масштаб подготовки.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →