B2C-сервис к высокой нагрузке готовят в таком порядке: оценивают пик по событию (рассылка, акция, запуск рекламы), выделяют критический путь, проверяют его нагрузочным тестом на данных, близких к боевым, выносят из пользовательского запроса всё, что можно сделать позже, и договариваются, какие функции отключаются первыми. Ускорять весь сервис сразу не нужно: узких мест обычно два-три, и найти их можно измерением.

Здесь процедура подготовки к известному событию. Профили нагрузки и архитектурные решения для сервиса, который растёт постоянно, описаны на странице «Разработка высоконагруженного веб-сервиса для B2C».

Коротко. Пик определяет событие, а не размер аудитории. Нагрузку проверяют сценарием «зашёл, выбрал, оплатил», а не главной страницей. Всё, что может подождать, уходит в очередь, а порядок отключения функций записывается до события.

Как оценить пик: от события к запросам

Размер аудитории не говорит о пике. Сервис с большой базой клиентов спокойно живёт в обычный день и ложится на рассылке, которая приводит большую часть аудитории за полчаса. Поэтому оценка начинается с события и идёт по воронке:

Этап воронкиЧто нагружает сервисОткуда взять оценку
Рассылка или рекламаГлавная страница, страница акции, картинкиРазмер рассылки, доля открывших, статистика прошлых акций
Вход и регистрацияПроверка пароля, коды по SMS или почте, создание записейДоля пришедших, которым нужен вход, лимиты провайдера кодов
ВыборКаталог, поиск, фильтры, остатки или свободное времяЧисло просмотров на посетителя по прошлым событиям
Оформление и оплатаЗапись в основную базу, обращения к провайдеру оплатыКонверсия по прошлым акциям, пропускная способность провайдера
После оплатыПисьма, чеки, обмен с учётом, уведомленияЧисло платежей и скорость, с которой обработчики их разбирают

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

Критический путь: что должно работать при любых условиях

Не все функции равны. Перед событием записывается список, в котором каждая функция получает класс:

КлассПримерыЧто делаем при перегрузке
ОбязательноеВход, поиск товара или времени, оформление, оплата, подтверждениеЗащищаем любой ценой: выделенные ресурсы, отдельные очереди, никаких тяжёлых запросов рядом
ОткладываемоеПисьма, чеки, обмен с учётом, начисление бонусов, аналитикаВыполняем после, через очередь; задержка в минуты допустима
ОтключаемоеРекомендации, истории просмотров, счётчики «сейчас смотрят», отзывыОтключаем флагом без выпуска новой версии, страницы показываются без этих блоков

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

Нагрузочный тест, который что-то показывает

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

  • Сценарий, а не страница. Виртуальный пользователь заходит, ищет, добавляет в корзину, входит, оформляет, оплачивает на тестовой стороне провайдера. Доли шагов берутся из реальной воронки.
  • Данные как в бою. Тест на пустой базе врёт: индексы и планы запросов ведут себя иначе на реальном объёме. Копия обезличивается и размещается на отдельном стенде, не рядом с боевой системой.
  • Нагрузка растёт ступенями до отказа. Нужно увидеть не «выдержали», а где и как именно сломалось: что выросло первым, база, очередь или приложение.
  • Внешние сервисы заменены заглушками или тестовыми средами, с провайдерами заранее договариваются. Нагружать боевую оплату или рассылку SMS нельзя.
  • Измеряется то, что видит клиент: время ответа, доля ошибок, длина очередей, загрузка базы. Среднее скрывает худших клиентов, поэтому смотрят на медленный хвост.

Результат теста — не вердикт «выдержали», а список: что сломалось, при какой нагрузке, что чинить первым. После исправления тест повторяют, иначе неизвестно, помогло ли.

Где обычно ломается: симптом, причина, первая проверка

Причины повторяются от сервиса к сервису. Таблица помогает не гадать:

СимптомЧастая причинаПервая проверка
Страницы медленнеют, база загруженаЗапросы без подходящего индекса, лишние запросы на каждый элемент спискаЖурнал медленных запросов, число запросов на одну страницу
Ошибки «нет соединения с базой»Исчерпан пул соединений: долгие запросы удерживают соединения, а новые ждутЧисло соединений и самые долгие запросы в момент пика
Оформление тормозит, остальное быстроБлокировки на общей строке: счётчик заказов, остаток популярного товара, общий балансОжидания блокировок в базе, запросы, которые обновляют одну и ту же запись
Запрос ждёт письма или чекаТяжёлая операция выполняется внутри пользовательского запросаЧто вызывается до ответа клиенту
Всё зависает при сбое одного сервисаНет ограничения времени ожидания на запрос к внешнему сервисуТаймауты и повторы в клиенте к провайдеру
Нагрузка падает рывками после очистки кэшаВсе запросы разом идут в базу, пока кэш заполняетсяКак и когда сбрасывается кэш, есть ли прогрев

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

Очередь вместо ожидания: что вынести из запроса

Клиенту нужен ответ «заказ принят», а не «письмо отправлено». Всё, что не влияет на этот ответ, уходит в фоновые задачи через очередь:

  • письма, SMS, сообщения в мессенджерах;
  • формирование чеков и документов;
  • передача заказа в учётную систему и обновление остатков;
  • начисление бонусов, пересчёт рейтингов и аналитики.

У очереди три правила. Задача выполняется повторно без вреда (идемпотентность): иначе сбой и повтор дают два письма и два списания. Очередь имеет ограничение скорости для внешних сервисов, чтобы не превысить их лимиты. И у неё есть мониторинг длины: растущая очередь на пике — нормальное явление, растущая после него — повод для тревоги. Выбор между PostgreSQL и RabbitMQ для очереди определяется объёмом и тем, что уже есть в системе.

Свои клиенты и боты: ограничения на уровне приложения

Часть нагрузки создают не покупатели. Боты перебирают пароли, запрашивают коды по SMS (каждый код стоит денег и упирается в лимиты провайдера), многократно нажимают кнопки в надежде успеть первым. На уровне приложения делаются ограничения:

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

Защиту от DDoS-атак мы не делаем: это задача оператора связи или специализированного провайдера. Но ограничения приложения нужны независимо от неё, потому что массовая «честная» нагрузка выглядит для сервера так же. Как ограничивать частоту запросов в программном интерфейсе, разобрано в статье о проектировании API.

Деградация вместо падения: заранее записанный порядок

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

Отдельно записывается страница «мы перегружены»: простая, из кэша, с обещанием вернуться и кнопкой повторить. Она выглядит скромно, но лучше белого экрана. Как соотносится доступность с обещаниями клиентам, описано в статье о «трёх девятках». Нужна ли для вашего сервиса архитектура сложнее одного монолита с очередями, помогает решить материал «Микросервисы или монолит».

План подготовки и день события

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

  1. За четыре недели. Оценка пика по воронке, список критического пути, согласование лимитов с провайдерами оплаты и SMS.
  2. За три недели. Первый нагрузочный тест, список найденных узких мест, исправления.
  3. За две недели. Повторный тест, очереди и выключатели функций, страница перегрузки.
  4. За неделю. Заморозка изменений: новые функции не выпускаются, только исправления ошибок. Репетиция отката.
  5. В день события. Дежурит ваша команда: графики очередей, ошибок, загрузки базы, понятный порядок решений, кто отключает функции и по какому признаку.
  6. После события. Разбор: что показали графики, где были неожиданности, что исправить до следующего раза.

Круглосуточного дежурства у нас нет. Если на день события нужна наша помощь, это отдельная договорённость в рабочее время; ночного дежурства мы не обещаем.

Что делаем мы и с чего начать

Начинаем с обследования: 200 000 ₽ и 2–3 недели за один сервис, 350 000 ₽ и 3–4 недели, если он связан с несколькими системами. На выходе документ с оценкой пика, критическим путём, найденными узкими местами по коду и конфигурации, планом нагрузочной проверки и вилкой бюджета. Стоимость вычитается из первого этапа, если продолжаете с нами, а документом можно пользоваться и без нас.

Дальше, если нужно, пилот на самом узком месте, затем вывод в эксплуатацию этапами, и на любой ступени можно остановиться. Мы работаем с одним сервисом или участком, а не перестраиваем всю систему за десятки миллионов, не защищаем от DDoS и не дежурим круглосуточно. Исходники лежат в вашем репозитории с первого коммита. Описание услуги — на странице «Разработка высоконагруженного веб-сервиса для B2C», архитектурные работы — на странице про микросервисы и высокую нагрузку, цены и сроки — на странице «Тарифы».

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

Как подготовить B2C-сервис к высокой нагрузке?

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

Как понять, какую нагрузку выдержит сервис?

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

Нужны ли микросервисы, чтобы выдержать пик?

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

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

Не стоит. Тест идёт на отдельном стенде с обезличенной копией данных, внешние сервисы заменяются заглушками или тестовыми средами. Нагрузка на боевую оплату и боевую рассылку SMS создаёт расходы и риск для клиентов.

Что делать, если уже случилась авария на акции?

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

Защищаете ли вы от DDoS?

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

Дежурите ли вы в день акции?

Круглосуточной дежурной смены у нас нет. В день события дежурит ваша команда по записанному порядку; наша помощь в рабочее время возможна по отдельной договорённости.

Сколько стоит подготовка сервиса к нагрузке?

Обследование — 200 000 ₽ или 350 000 ₽ при нескольких системах, оно вычитается из первого этапа. Пилот на узком месте — 150 000–400 000 ₽, тяжёлый пилот — 400 000–1 200 000 ₽, вывод в эксплуатацию — от 1 500 000 ₽ этапами по 300 000–700 000 ₽. Вилка сужается по результатам обследования.