Нагрузочное тестирование сайта: что это и как провести перед запуском
Нагрузочное тестирование — это проверка того, как сайт или веб-сервис работает, когда к нему одновременно обращается много пользователей. Специальная программа имитирует посетителей: открывает каталог, ищет товары, кладёт их в корзину, оформляет заказ. Команда в это время смотрит на время ответа, долю ошибок и загрузку сервера. Итог — цифры: сколько запросов в секунду выдерживает сайт, где он начинает тормозить и что сломается первым.
Скорость загрузки для одного посетителя — отдельная тема, мы разобрали её в статье о скорости загрузки сайта. Здесь речь о поведении сайта под нагрузкой.
Что такое нагрузочное тестирование простыми словами
Сайт, который открывается за секунду у одного посетителя, при тысяче одновременных может отвечать по 15 секунд или отдавать 502. Причина — ограниченные ресурсы: у сервера конечное число процессов PHP, у базы данных — соединений, у диска — операций в секунду. Пока очередь пустая, этого не видно.
Нагрузочный тест создаёт эту очередь искусственно и заранее. Генератор нагрузки отправляет запросы по сценарию и заданному профилю, а система мониторинга фиксирует, какой ресурс заканчивается первым. Такое место называют узким: пока его не расширить, добавлять мощность в другом месте бесполезно.
Важно отличать тест от атаки. DDoS — это злонамеренная нагрузка, её цель — положить сайт. Нагрузочный тест согласован с владельцем, проводится по плану, с мониторингом и возможностью остановиться в любой момент. Технически трафик похож, поэтому тестировать можно только свой сайт или чужой — с письменного разрешения владельца. Нагрузка на чужой ресурс без согласия — по сути DDoS: такие действия могут квалифицировать по статьям 272 и 273 УК РФ. Об атаках и защите — в статье что такое DDoS-атака.
Виды нагрузочного тестирования: от штатного пика до отказа
Под общим названием скрывается несколько разных проверок. Отличаются они профилем нагрузки и вопросом, на который отвечают.
| Вид | Что проверяет | Как нагружают | Длительность |
|---|---|---|---|
| Нагрузочное (load) | Держит ли сайт ожидаемый пик с нужным временем ответа | Плавно выходят на целевой RPS и держат его | 30–60 минут |
| Стресс-тест | Где предел, как сайт деградирует и восстанавливается ли сам | Ступенями наращивают нагрузку до отказа, затем снимают | До отказа плюс время на восстановление |
| Стабильности (soak, endurance) | Утечки памяти, разрастание логов и очередей, деградация со временем | 70–80% от пика без перерыва | От 4 до 24 часов и дольше |
| Спайк-тест | Резкий всплеск после рассылки, пуша, ТВ-эфира | Рост в 5–10 раз за секунды или минуту | Минуты, несколько повторов |
Интернет-магазину перед запуском обычно хватает двух проверок: нагрузочной на целевой пик и стресс-теста, чтобы знать запас. Тест стабильности нужен сервисам с круглосуточной нагрузкой, спайк-тест — если трафик приходит волнами после рассылок и рекламы.
Когда бизнесу нужно нагрузочное тестирование
Тест окупается, когда у простоя есть понятная цена, а нагрузка заметно вырастет или изменится инфраструктура:
- Распродажа и сезонный пик. Чёрная пятница, 8 Марта, старт сезона: трафик растёт в разы, и каждый час простоя — прямые потери выручки.
- Крупная рекламная кампания. Посевы в Telegram, медийная реклама, Директ с большим бюджетом. Упавший сайт превращает бюджет в оплаченные ошибки 502.
- Спайки: ТВ-эфир, СМИ, блогер, рассылка. За минуты приходит столько людей, сколько обычно за день. Письмо на 200 тысяч адресов — спайк, который вы создаёте сами.
- Запуск нового сайта. Статистики ещё нет, и тест — единственный способ проверить архитектуру до клиентов.
- Миграция. Переезд на новый сервер или CMS, обновление PHP или ядра Битрикс. После неё сайт может выдерживать меньше, даже если в браузере всё открывается быстро.
Закладывайте тест за 3–4 недели до события: первый прогон почти всегда находит узкое место, а на исправление и повторную проверку нужно время.
Метрики нагрузочного тестирования: что смотреть в отчёте
Генератор нагрузки показывает, что видит «пользователь». Мониторинг сервера объясняет, почему стало медленно.
| Метрика | Что показывает | На что смотреть |
|---|---|---|
| RPS (запросов в секунду) | Какую интенсивность выдерживает сайт | Растёт ли RPS вместе с нагрузкой или упёрся в потолок |
| Время ответа p95 и p99 | Сколько ждут 95% и 99% запросов | Порог задают заранее, например p95 до 800 мс для страниц каталога |
| Доля ошибок | Ответы 5xx, таймауты, обрывы соединений | Обычно допускают не больше 1%, для оплаты — ноль |
| CPU, RAM, диск | Насыщение ресурсов сервера | Загрузка процессора под 100%, уход в swap, очередь дисковых операций |
| База данных | Соединения, медленные запросы, блокировки | Лимит соединений, рост медленных запросов в логе |
RPS в нагрузочном тестировании — число запросов, которое сервер обрабатывает за секунду. Цель теста формулируют в RPS: «пользователи онлайн» мало что говорят — один посетитель делает запрос раз в минуту, другой десять раз в секунду.
Профиль нагрузки: как посчитать целевой RPS по данным Метрики
Цифра «с потолка» вроде «пусть выдержит 10 000 пользователей» — частая ошибка. Профиль строят по реальной статистике: нужны данные Яндекс Метрики за самый загруженный период прошлого года и план маркетинга на предстоящий пик.
- Пиковый час. В отчёте по времени найдите час с максимумом визитов. Допустим, в прошлую распродажу было 60 000 визитов в день, из них в пиковый час — 6 000 (10% суточных).
- Глубина просмотра. Пусть в среднем 6 страниц за визит. Это 36 000 просмотров в час, или 10 просмотров страниц в секунду.
- Запросы к серверу. Статика уходит на CDN или отдаётся Nginx без участия PHP. Динамических запросов на просмотр — HTML-страница плюс 2–3 AJAX (фильтр, корзина, подсказки поиска), около 4. Итого 40 RPS к приложению.
- Рост на событие. Маркетинг ждёт в 5 раз больше трафика: 200 RPS.
- Запас. Умножаем на 1,5 на ошибку прогноза: цель теста — 300 RPS при p95 до 800 мс и ошибках меньше 1%.
Число одновременных посетителей оценивают по закону Литтла: L = λ · W, где λ — поток визитов в секунду, W — средняя длительность визита. 6 000 визитов в час — это λ ≈ 1,67 визита в секунду; при визите 5 минут (W = 300 секунд) L ≈ 1,67 × 300 ≈ 500 человек на сайте одновременно. При пятикратном росте в распродажу — около 2 500. Эти цифры нужны, чтобы проверить сессии и лимиты соединений.
Второе, что берут из Метрики, — сценарии. Не нужно тестировать весь сайт: достаточно 3–5 путей, которые дают основную нагрузку и выручку, например 60% — каталог и карточки, 25% — поиск и фильтр, 10% — корзина, 5% — оформление заказа. Тест должен повторять реальный трафик, а не бить в одну главную.
Инструменты для нагрузочного тестирования в 2026 году
Основные инструменты бесплатны и с открытым кодом, выбор зависит от того, кто пишет сценарии.
| Инструмент | Сценарии | Сильные стороны | Кому подходит |
|---|---|---|---|
| k6 (Grafana Labs) | JavaScript или TypeScript | Сценарии как код, пороги «прошёл — не прошёл», легко встраивается в CI | Командам разработки |
| Apache JMeter | Графический интерфейс, Groovy | Много протоколов и плагинов, запись сценария через прокси | QA-инженерам, сложным корпоративным системам |
| Gatling | Java, Kotlin, Scala, JavaScript | Экономно расходует ресурсы генератора, наглядные HTML-отчёты | Java-командам, высоким нагрузкам |
| Locust | Python | Простые сценарии, веб-интерфейс, распределённый запуск | Командам на Python |
| Яндекс.Танк и Pandora | Конфигурация YAML, сценарии Pandora на Go | Очень высокий RPS с одной машины | Высоконагруженным сервисам |
Облачный Yandex Load Testing на базе Танка закрылся 1 июля 2026 года, сам Яндекс предлагает переносить сценарии на k6. Поэтому генераторы нагрузки сейчас обычно запускают на своих серверах или арендованных на время теста виртуальных машинах в российском облаке. «Онлайн-тесты», которые шлют несколько сотен запросов в главную, годятся лишь для грубой прикидки.
Пример сценария k6
Сценарий выходит за 10 минут на 300 RPS из расчёта, держит их 20 минут и признаёт тест проваленным, если p95 больше 800 мс, p99 больше 2 секунд или ошибок больше 1%. Исполнитель ramping-arrival-rate задаёт интенсивность запросов, а не число виртуальных пользователей.
import http from 'k6/http';
import { check } from 'k6';
const BASE = __ENV.BASE_URL || 'https://stage.example.ru';
export const options = {
scenarios: {
catalog: {
executor: 'ramping-arrival-rate',
startRate: 10,
timeUnit: '1s',
preAllocatedVUs: 100,
maxVUs: 1000,
stages: [
{ target: 300, duration: '10m' },
{ target: 300, duration: '20m' },
{ target: 0, duration: '2m' },
],
},
},
thresholds: {
http_req_failed: ['rate<0.01'],
http_req_duration: ['p(95)<800', 'p(99)<2000'],
},
};
export default function () {
const page = Math.ceil(Math.random() * 20);
const res = http.get(`${BASE}/catalog/?PAGEN_1=${page}`);
check(res, { 'status 200': (r) => r.status === 200 });
}
Запуск: k6 run -e BASE_URL=https://stage.example.ru load.js. В реальном проекте сценариев несколько — по долям из Метрики.
Где тестировать: стенд или боевой сайт
Идеальный вариант — отдельный стенд с той же конфигурацией, что и продакшен: те же версии PHP и базы, те же настройки кеша, сравнимые мощности и полная копия данных. Слабая копия покажет неверные цифры, пустая база — слишком хорошие.
Если стенда нет и тест идёт на боевом сайте:
- выбрать ночное окно и заранее договориться, кто и по какому признаку останавливает тест;
- переключить оплату в тестовый режим платёжного сервиса, а SMS, письма и отправку заказов в 1С или CRM — на заглушки, иначе тест создаст тысячи фиктивных заказов;
- предупредить хостинг-провайдера: иначе он может принять тест за атаку и заблокировать аккаунт, а на виртуальном хостинге вы упрётесь в лимиты тарифа;
- добавить IP генераторов в белый список WAF и защиты от DDoS. иначе вы проверите не сайт, а фильтр с капчей и ошибкой 429;
- исключить IP генераторов в фильтрах Метрики, чтобы не испортить статистику и автостратегии Директа.
Как провести нагрузочное тестирование сайта: этапы
- Цели и критерии. Целевой RPS, p95, p99, доля ошибок — в цифрах, до старта.
- Профиль и сценарии. Пиковый час, доли сценариев, тестовые данные: аккаунты, товары, промокоды.
- Стенд и мониторинг. CPU, память, диск, база, PHP-FPM, Nginx.
- Скрипты и отладочный прогон. Малая нагрузка, чтобы убедиться, что сценарии проходят и ответы корректны: 200 со страницей ошибки — не успех.
- Основные прогоны. Нагрузочный на цель, затем стресс до отказа. Генератор тоже мониторят: если у него 100% CPU, упёрся он, а не сайт.
- Анализ и отчёт. Предел, узкие места, рекомендации с приоритетами.
- Исправления и повторный прогон. Без повтора нельзя сказать, что оптимизация сработала.
Частые ошибки на этих этапах: генератор запускают с офисного ноутбука, и канал или процессор кончаются раньше, чем ресурсы сервера; не снимают метрики сервера и получают «сайт упал на 150 RPS» без ответа почему; тестируют один раз перед запуском, хотя через год и десяток доработок производительность уже другая — регулярные прогоны удобно встроить в CI/CD.
Узкие места: что обычно ломается первым
У сайтов на PHP узкие места повторяются:
- База данных. Запросы без индексов: на пустой базе — миллисекунды, на каталоге в 200 тысяч товаров — секунды, под нагрузкой — очередь и блокировки. Лечится индексами и кешированием.
- Воркеры PHP-FPM.
pm.max_childrenограничивает число одновременных PHP-запросов. Когда все процессы заняты, запросы ждут, а Nginx отдаёт 502 или 504. Поднимать лимит вслепую нельзя: каждому процессу нужна память, сервер уйдёт в swap. - Кеш. Его нет, он маленький или сбрасывается при каждом изменении цен. Кеш, который обнуляет выгрузка из 1С раз в 10 минут, почти не помогает.
- Сессии. Файловые сессии PHP блокируются на время запроса, и параллельные AJAX-запросы посетителя встают в очередь. Помогает перенос сессий в Redis или Memcached.
- Внешние API. Расчёт доставки, проверка остатков, геолокация. Пока сервис отвечает 2 секунды, запрос держит PHP-процесс, и воркеры заканчиваются. Нужны таймауты, кеш и асинхронные вызовы.
Работы по итогам делятся на три группы: настройки сервера (Nginx, PHP-FPM, база, кеш), доработка кода (запросы, кеширование, отказ от синхронных внешних вызовов) и масштабирование (мощнее сервер, отдельный сервер базы, CDN для статики). Серверную часть обычно закрывает настройка и сопровождение сервера, кодовую — доработка сайта по результатам отчёта. Если статика и картинки забирают канал, помогает CDN.
Порядок важен: сначала устраняют узкое место в коде и настройках, потом докупают железо. Сервер вдвое мощнее не спасёт от запроса без индекса.
Особенности тестирования сайтов на 1С-Битрикс и WordPress
1С-Битрикс. Композитный режим отдаёт готовый HTML из кеша, и тест главной покажет отличные цифры, которые ничего не говорят о корзине, поиске, фильтре и личном кабинете. Поэтому в сценариях обязательны некешируемые действия и авторизованные пользователи. Ещё два частых узких места: агенты, которые выполняются на хитах посетителей (их переводят на cron), и хранение сессий. Встроенный «Монитор производительности» найдёт медленные страницы, но теста не заменит.
WordPress и WooCommerce. Плагины страничного кеша (WP Super Cache, W3 Total Cache, LiteSpeed Cache) обслуживают анонимов, а авторизованные пользователи и корзина WooCommerce идут мимо кеша в PHP и базу. Нагрузку дают admin-ajax.php, обновление фрагментов корзины и wp-cron, который по умолчанию запускается на визитах посетителей — его отключают и переносят в системный cron. Объектный кеш в Redis разгружает базу.
Чек-лист: подготовка к нагрузочному тестированию сайта
- Определено событие и дата: распродажа, кампания, запуск или миграция
- По данным Метрики посчитан целевой RPS с запасом и заданы пороги p95, p99 и доли ошибок
- Выбраны 3–5 сценариев с долями, включая некешируемые (корзина, поиск, авторизация); готовы тестовые аккаунты и данные
- Есть стенд с конфигурацией и данными как на боевом сайте, или согласовано ночное окно на продакшене
- Оплата, SMS, письма и выгрузка заказов в 1С или CRM переключены на заглушки
- Хостинг предупреждён, IP генераторов в белом списке WAF и исключены из Метрики
- Настроен мониторинг сервера, базы и PHP-FPM, есть свежая резервная копия и ответственный за остановку теста
- Запланированы исправления и повторный прогон до события
