Как подготовить сайт к высокой нагрузке: Black Friday, реклама, вирусный трафик
Компания запускает большую рекламную кампанию. Маркетинг радуется. Продажи ждут поток заказов. DevOps — нет. Потому что успешная рекламная кампания может стать для сайта почти тем же, чем DDoS-атака: тысячи пользовате…
Компания запускает большую рекламную кампанию. Маркетинг радуется. Продажи ждут поток заказов. DevOps — нет. Потому что успешная рекламная кампания может стать для сайта почти тем же, чем DDoS-атака: тысячи пользователей одновременно открывают каталог, загружают изображения, применяют фильтры, авторизуются, кладут товары в корзину и отправляют запросы на оплату. И если инфраструктура к этому не готова, возникает неприятный парадокс: компания заплатила за трафик, привела потенциальных покупателей — и потеряла их из-за медленного или недоступного сайта.
Black Friday, крупная email-рассылка, запуск нового продукта, рекламная интеграция у блогера или внезапно завирусившееся видео отличаются источником трафика, но техническая проблема одна: система должна пережить резкое увеличение количества запросов. Подготовка начинается не с увеличения мощности сервера. Сначала нужно понять, где находится предел системы.
Что происходит с сайтом при росте трафика
Обычно сайт не падает мгновенно. Сначала увеличивается время ответа. Страница, которая раньше открывалась за 500 миллисекунд, начинает отвечать две секунды. Потом пять. Потом десять. Часть пользователей закрывает вкладку. Оставшиеся продолжают отправлять запросы. Количество параллельных соединений растёт. База данных начинает обрабатывать очередь запросов. API сторонних сервисов упираются в лимиты. Сервер пытается выполнить всё одновременно. В какой-то момент один перегруженный компонент начинает замедлять остальные. Поэтому высокая нагрузка — это редко проблема только CPU.
Перед большой рекламной кампанией стоит проверить CPU, использование памяти, количество соединений с базой данных, ограничения API, свободное место на диске, пропускную способность сети и состояние внешних сервисов. Иногда сервер загружен всего на 30%, а сайт уже работает плохо. Причина может находиться в базе данных. Или в стороннем API. Или в слишком маленьком пуле соединений. Или в одном запросе, который выполняется три секунды и блокирует остальные операции.
Load testing: сначала создаём нагрузку искусственно
Лучше узнать предел сайта во время теста, чем в момент запуска рекламы. Для этого используется нагрузочное тестирование. Его задача — смоделировать действия реальных пользователей и посмотреть, как система ведёт себя при увеличении количества запросов. Важно тестировать не абстрактные запросы к главной странице, а реальные пользовательские сценарии. Например: пользователь открывает каталог → применяет фильтр → открывает карточку товара → добавляет товар в корзину → переходит к оформлению заказа → создаёт заказ. Именно такие цепочки создают реальную нагрузку на приложение, базу данных, кеш, API и систему оплаты.
При этом существует несколько разных типов нагрузочного тестирования.
Load testing
Load-тест отвечает на вопрос: выдерживает ли система ожидаемую нагрузку? Если маркетинг прогнозирует 5 000 пользователей в течение часа, можно воспроизвести похожий поток запросов в тестовой среде. При этом измеряется не только количество успешных запросов. Важно смотреть на latency, ошибки, загрузку инфраструктуры и деградацию производительности. Сайт может формально отвечать HTTP 200, но если страница загружается 12 секунд, для бизнеса это всё равно проблема.
Stress testing
Stress-тест нужен для поиска предела. Нагрузка постепенно увеличивается до момента, когда система начинает деградировать. Например: 100 пользователей одновременно. 1 000. 2 000. 5 000. В определённой точке время ответа начинает резко увеличиваться или появляются ошибки. Это и есть зона, которую необходимо исследовать. Главный вопрос stress-теста: что сломается первым? Приложение? База данных? Redis? Сторонний API? Платёжный сервис? Именно эта информация помогает правильно инвестировать в инфраструктуру.
Spike testing
Spike-тест имитирует резкий скачок нагрузки. Например, блогер публикует ссылку. За минуту на сайт приходит 20 000 человек. Такой сценарий отличается от постепенного увеличения трафика. Автоматическое масштабирование может просто не успеть добавить новые серверы. Пул соединений с базой заканчивается раньше. Кеш начинает одновременно запрашивать одни и те же данные. Поэтому для рекламных запусков spike-тест зачастую важнее классического нагрузочного теста.
Soak testing
Soak-тест проверяет длительную работу системы. Сайт может прекрасно выдерживать 2 000 пользователей десять минут, но начать деградировать через шесть часов. Причинами бывают утечки памяти, накопление логов, слишком большое количество открытых соединений, рост очередей или фоновые процессы. Поэтому для ecommerce-проектов важно проверять не только пик нагрузки, но и способность системы стабильно работать длительное время.
Кеширование: самый дешёвый запрос — тот, которого не было
Одна из самых эффективных оптимизаций — уменьшить количество вычислений. Если десять тысяч пользователей запрашивают один и тот же каталог товаров, необязательно десять тысяч раз выполнять одинаковые запросы к базе данных. Результат можно сохранить в кеше. Кеширование может происходить на нескольких уровнях. Браузер пользователя способен хранить изображения, CSS и JavaScript. CDN может отдавать статические файлы без обращения к основному серверу. Приложение может использовать Redis для хранения популярных данных. Reverse proxy может кешировать готовые HTTP-ответы.
Главная задача кеша — не просто ускорить сайт. Он уменьшает количество работы, которую приходится выполнять основной системе. Именно поэтому кеш становится особенно важным во время массовых рекламных кампаний. Но есть и другая сторона. Нужно заранее определить правила инвалидирования. Если цена товара изменилась, пользователь должен увидеть новую цену, а не сохранённую версию из кеша. Поэтому эффективное кеширование — это баланс между скоростью и актуальностью данных.
База данных обычно становится главным ограничением
Backend-приложения масштабировать сравнительно просто. Можно запустить несколько экземпляров приложения и распределить запросы через load balancer. С базой данных всё сложнее. Именно поэтому во время нагрузочного тестирования необходимо отдельно наблюдать за количеством соединений, временем выполнения запросов, блокировками, индексами и медленными SQL-запросами. Один неоптимальный запрос может практически не ощущаться при 20 пользователях. При 5 000 пользователей он превращается в серьёзную проблему. Особенно опасны запросы без необходимых индексов, N+1 queries, большие JOIN, сортировки по неиндексированным полям и попытки читать слишком много данных за один запрос.
Перед запуском крупной рекламной кампании полезно включить сбор slow queries и проверить наиболее частые операции. Иногда добавление одного правильного индекса даёт больший эффект, чем увеличение мощности сервера в несколько раз.
Очереди задач: пользователю не обязательно ждать всё
Ещё один важный принцип масштабируемых систем: не каждую операцию нужно выполнять внутри HTTP-запроса. Представим оформление заказа. После создания заказа система может отправить письмо, уведомить CRM, сформировать PDF, отправить данные в аналитику и обновить склад. Если выполнять всё последовательно, пользователь будет ждать завершения каждой операции. Надёжнее сохранить заказ и сразу подтвердить его создание. Остальную работу можно отправить в очередь. Для этого используются Celery, RabbitMQ, Kafka, Redis Queue и другие инструменты.
Очередь позволяет сгладить пики нагрузки. Даже если в течение минуты создаётся несколько тысяч заказов, фоновые workers смогут обработать дополнительные операции постепенно. Особенно важно вынести в фон всё, что не требуется пользователю мгновенно.
Rate limiting: иногда систему нужно защищать от собственных пользователей
При высокой нагрузке полезно ограничивать количество запросов. Rate limiting часто воспринимают исключительно как защиту от атак, но он полезен и в обычном бизнес-приложении. Например, пользователь несколько раз нажимает кнопку оплаты. Frontend из-за ошибки начинает отправлять запрос каждую секунду. Бот постоянно обращается к API. Интеграция партнёра начинает создавать сотни запросов одновременно. Без ограничений такие ситуации могут ухудшить работу системы для всех пользователей. Rate limiting позволяет установить разумные правила.
Например, не больше определённого количества запросов к API от одного клиента за минуту. Главное — применять ограничения аккуратно. Пользователь не должен неожиданно получить ошибку именно в момент покупки.
Autoscaling: больше серверов, когда они действительно нужны
Если приложение спроектировано горизонтально масштабируемым, количество экземпляров backend можно увеличивать автоматически. При росте CPU, количества запросов или длины очереди система запускает дополнительные instances. Когда нагрузка снижается — лишние instances выключаются. Это позволяет не держать дорогостоящую инфраструктуру постоянно. Но autoscaling нельзя считать магической кнопкой. Если проблема находится в базе данных, запуск ещё двадцати backend-серверов способен сделать ситуацию даже хуже. Каждый новый instance создаст дополнительные соединения и запросы к той же базе.
Поэтому масштабировать нужно только после понимания архитектурного bottleneck. Также важно учитывать скорость масштабирования. При вирусном трафике нагрузка может вырасти за несколько секунд. Если новый instance запускается две минуты, система должна пережить эти две минуты самостоятельно. Именно поэтому autoscaling хорошо работает вместе с кешем, очередями и заранее подготовленным запасом ресурсов.
CDN снимает нагрузку с основного сервера
Изображения, JavaScript, CSS, видео и другие статические файлы необязательно отдавать с того же сервера, где работает приложение. Для этого используются CDN. Файлы копируются на распределённые серверы и отдаются пользователям из ближайшей точки присутствия. Это решает сразу несколько задач. Снижается нагрузка на основной сервер. Уменьшается сетевой трафик. Контент быстрее загружается для пользователей из разных регионов. Для ecommerce это особенно важно. Карточка товара может содержать несколько тяжёлых фотографий. Если десятки тысяч пользователей одновременно начнут загружать их с одного сервера, статический контент способен занять значительную часть доступной пропускной способности.
CDN позволяет отделить эту нагрузку от backend.
Не забывайте про внешние сервисы
Инфраструктура компании может выдерживать 10 000 запросов в секунду. Но это не означает, что всё приложение выдержит такую нагрузку. Сайт часто зависит от внешних систем. Платёжные сервисы. CRM. SMS-провайдеры. Email-сервисы. Сервисы доставки. Карты. Антифрод. Авторизация. Внешнее API может иметь ограничение, например, на количество запросов в минуту. Когда трафик резко увеличивается, ваш сайт начинает упираться уже не в собственную инфраструктуру, а в лимит партнёра. Поэтому во время подготовки к нагрузке необходимо составить карту внешних зависимостей.
Для каждой зависимости нужно понимать лимиты, timeout, retry policy и поведение системы при недоступности сервиса. Если CRM временно не отвечает, покупатель всё равно должен иметь возможность оформить заказ. Интеграцию с CRM можно выполнить позже через очередь.
Retry может помочь. А может окончательно положить систему
Один из опасных сценариев высокой нагрузки связан с повторными запросами. Представим, что внешний API начал отвечать медленнее. Приложение получает timeout и повторяет запрос. Если одновременно работают тысячи пользователей, количество запросов к проблемному сервису удваивается. Он начинает отвечать ещё медленнее. Приложение снова делает retry. Получается retry storm. Поэтому повторные запросы должны использовать backoff — постепенно увеличивающийся интервал ожидания. Для некоторых интеграций также применяется circuit breaker.
Если внешний сервис явно недоступен, приложение временно прекращает отправлять к нему запросы. Это позволяет основной системе продолжить работу.
Нагрузочное тестирование должно измерять бизнес-сценарии
Главная ошибка performance testing — измерять только requests per second. Для бизнеса важнее другое. Может ли пользователь открыть каталог? Может ли добавить товар? Может ли оформить заказ? Не появятся ли дубли заказов? Не потеряется ли оплата? Не будут ли товары продаваться после окончания остатка? Поэтому вместе с техническими метриками нужно контролировать бизнес-метрики. Например, количество успешно созданных заказов, процент ошибок оплаты, время оформления покупки и число потерянных операций. Система может выдерживать огромный RPS на главной странице и при этом падать на checkout.
Для ecommerce второй показатель значительно важнее первого.
Что проверять перед большой рекламной кампанией
Перед Black Friday, запуском продукта или масштабной закупкой рекламы полезно пройти один общий технический чек-лист:
- определить ожидаемый и пиковый трафик;
- провести Load, Stress, Spike и при необходимости Soak testing;
- проверить CPU, memory, disk и network;
- проанализировать database connections и slow queries;
- проверить индексы базы данных;
- вынести тяжёлые операции в фоновые очереди;
- настроить кеширование;
- подключить CDN для статики;
- проверить rate limiting;
- протестировать autoscaling;
- проверить лимиты всех внешних API;
- настроить timeout, retry и circuit breaker;
- проверить мониторинг и алерты;
- протестировать checkout и другие критические бизнес-сценарии;
- подготовить план действий на случай деградации системы.
Важно выполнить эту работу до запуска рекламы, а не после первых ошибок.
Самый дорогой сервер — тот, который упал во время продаж
Высокая нагрузка сама по себе не является проблемой. Наоборот, большой трафик обычно означает, что маркетинг сделал свою работу. Проблемой становится инфраструктура, которая не была подготовлена к успеху. Надёжная система строится не только на мощных серверах. Она строится на понимании ограничений. Кеш уменьшает количество вычислений. CDN снимает нагрузку со статического контента. Очереди сглаживают пики. Rate limiting защищает сервисы. Autoscaling добавляет ресурсы. Оптимизированная база данных быстрее обрабатывает запросы.
А нагрузочное тестирование показывает слабые места до того, как их обнаружат реальные покупатели. Поэтому перед большой рекламной кампанией стоит задать команде не вопрос: «Сколько у нас серверов?» А другой: «Что произойдёт, если через минуту пользователей станет в десять раз больше?» Если команда может показать результаты тестов и объяснить поведение системы при таком сценарии — сайт значительно лучше подготовлен к высокой нагрузке. Если ответ звучит как «думаем, выдержит» — нагрузочный тест лучше провести до запуска рекламы.