Нагрузочное тестирование сайта: JMeter, k6 и как читать результаты
В этой статье разберем, как спланировать и выполнить нагрузочное тестирование сайта, какие задачи решают JMeter и k6, на какие метрики смотреть (RPS, latency, percentiles), как читать отчеты и переводить цифры в понятные действия по оптимизации.
Нагрузочное тестирование сайта: базовые принципы
Нагрузочное тестирование — это проверка, как веб‑приложение ведет себя при ожидаемой и пиковых нагрузках. Цель — заранее обнаружить узкие места и убедиться, что система соответствует SLA/SLO по времени отклика и ошибкам.
Типы сценариев:
- Load (рабочая нагрузка) — подтверждаем, что система держит целевой RPS/число одновременных пользователей.
- Stress — поднимаем нагрузку до деградации, чтобы найти пределы.
- Spike — резкие скачки трафика (например, пуш‑рассылка).
- Soak (endurance) — длительный прогон для поиска утечек памяти, деградаций кэшей.
Что тестировать:
- Ключевые пользовательские пути (личный кабинет, корзина, оплата, поиск, фильтры).
- Критичные API эндпоинты, фоновые очереди, веб‑сокеты.
- Внешние интеграции (платежи, CRM) — по возможности через стабы.
План нагрузочного теста: от гипотез к числам
Перед запуском инструментов зафиксируйте исходные данные и допущения.
1) Бизнес‑цели и SLO
- Целевая нагрузка: средний и пиковый RPS/конкурентные пользователи.
- Время отклика: p95 ≤ X ms, p99 ≤ Y ms.
- Ошибки: error rate ≤ Z% (HTTP 5xx, 4xx по контексту).
2) Профиль трафика
- Доли сценариев (просмотр каталога 40%, поиск 25%, карточка 20%, корзина 10%, оплата 5%).
- Паттерны: суточные пики, маркетинговые кампании, сезонность.
3) Тестовая среда
- Соответствие продакшену: версия кода, конфиг, база данных, CDN, кэши, масштабы. Любые отличия описать в отчете.
- Изоляция: внешние интеграции стабить, e‑mail/SMS отключать.
4) Нагрузочный профиль
- Разогрев (warm‑up), затем ступени (ramp-up), плато, спад.
- Длительности: минимум 5–10 минут на плато для стабилизации метрик; soak — часы.
5) Мониторинг и артефакты
- Системные метрики: CPU, RAM, диск, сеть, GC, thread pools.
- APM/трейсинг: медленные транзакции, SQL, внешние вызовы.
- Логи: корреляция по trace/span/request id.
JMeter: настройка тестов без лишнего шума
Apache JMeter — классический инструмент с GUI и режимом командной строки.
Ключевые элементы плана (Test Plan):
- Thread Group: пользователи (Threads), Ramp-Up, Loop Count или Duration. Для сценариев с реалистической скоростью используйте Concurrency Thread Group из плагинов (JMeter Plugins).
- HTTP Request Defaults: базовый URL, таймауты (connect/read), сжатие.
- HTTP Header Manager: User-Agent, Accept, авторизация.
- CSV Data Set Config: тестовые данные (логины, товары).
- Timers (Constant/Uniform Random/Poisson): think time между действиями.
- Controllers: Transaction Controller (обернуть логические шаги сценария), Once Only Controller (логин один раз), If/While для ветвлений.
- Post-Processors: JSON Extractor/Regular Expression Extractor для корреляции токенов/ID.
- Assertions: проверка кода ответа, времени, тела.
Практика:
- В GUI настройте сценарии, провалидируйте ответы в View Results Tree, затем запускайте в non-GUI:
jmeter -n -t test.jmx -l results.jtl -e -o report
- Отключайте тяжелые слушатели (графики) в рантайме, используйте только запись в JTL.
- Для стабильной генерации RPS используйте Throughput Shaping Timer + Concurrency Thread Group.
- Скриптуйте через JSR223 (Groovy) при необходимости корреляции/логики.
Отчеты:
- HTML Dashboard: Throughput (RPS), Response Times (pct), Errors, Latencies, Timeseries. Фиксируйте p50/p90/p95/p99 и распределения.
k6: руководство для начинающих и запуск из кода
k6 — легковесный CLI с тестами на JavaScript, удобный для CI/CD и контейнеризации.
Быстрый старт (script.js):
- import http from 'k6/http';
- import { sleep, check } from 'k6';
- export const options = {
stages: [
{ duration: '2m', target: 100 },
{ duration: '10m', target: 100 },
{ duration: '2m', target: 0 }
],
thresholds: {
http_req_failed: ['rate<0.01'],
http_req_duration: ['p(95)<500']
}
};
- export default function () {
const res = http.get('https://example.com/catalog');
check(res, {
'status 200': r => r.status === 200,
});
sleep(1);
}
Запуск:
- k6 run script.js
- Для генерации отчета: вывод в JSON/InfluxDB/Prometheus + Grafana дашборды. Комбинируйте с k6 cloud или k6 operator в Kubernetes.
Плюсы k6:
- Детерминированные сценарии stages, гибкие thresholds (SLO в коде), легкая параметризация.
- Bogon‑friendly: мало накладных расходов, стабильная генерация нагрузки.
Метрики: RPS, latency, percentiles и что они значат
Базовые показатели:
- RPS/Throughput: сколько запросов в секунду обрабатывается успешно. Смотрите также конкурентных пользователей (VUs) и время «think time» в модели.
- Latency vs Response Time: latency — сетевые задержки; response time — полный отклик бэкенда. В инструментах чаще видим суммарное время ответа.
- Percentiles: p50 — медиана; p95/p99 — «хвосты», важны для UX. Фиксируйте их по ключевым транзакциям.
- Error rate: HTTP 5xx, 4xx (контекстно), timeouts, connection reset. В отчете разделяйте типы ошибок.
- Saturation: CPU, память, дисковая очередь, сетевые очереди, пул соединений БД, размер очередей брокеров.
Полезные принципы:
- Закон Литтла: L = λ × W. При фиксированном λ (RPS) рост W (время ответа) повышает L (очередь/конкурентность). Увидели рост p95 — ждите переполнение пулов.
- Профиль хвостов: увеличение p99 при стабильном p50 указывает на конкуренцию за ресурс (локи, GC, холодные кэши, N+1 запросы).
Как читать отчеты и находить узкие места
Подход к анализу:
1) Смотрите плато нагрузки. Стабильны ли RPS и задержки? Рваные графики намекают на троттлинг/GC/автоскейлинг.
2) Сравните p50/p95/p99 по транзакциям. Где разрыв максимальный — там и кандидаты в оптимизацию.
3) Коррелируйте спайки времени ответа с системными метриками. Примеры:
- Рост GC Pause → настройка heap, GC алгоритма, снижение аллокаций, кэш объектов.
- Высокие wait events в БД → индексы, batch‑запросы, пулы соединений.
- Насыщение CPU на одном узле — горячий shard, неравномерный трафик, отсутствие keep‑alive/HTTP/2.
4) Ошибки по кодам:
- 5xx: падения бэкенда, таймауты к БД, исчерпанные пулы (max_connections).
- 4xx: валидация, лимиты, CSRF — проверьте корректность сценария.
- Timeouts/Connect Reset: сетевые проблемы, LB health checks, firewall, SYN backlog.
5) Проверяйте кэш‑хиты (CDN, Redis). Разница в метриках «теплый vs холодный кэш» — показатель эффективности кэширования.
Что фиксировать в отчете:
- Цели, сценарии, конфигурация стенда и генератора нагрузки (ядра/память/сеть), версия кода.
- Профиль нагрузки (этапы, длительности), фактический RPS и распределения времени ответа.
- Диаграммы p50/p95/p99, error rate по типам, ресурсные метрики (CPU/RAM/IO/DB).
- Выводы и конкретные действия: индексация запроса X, увеличение пула Y, включение сжатия Z, изменение таймаутов.
Типовые узкие места и способы их локализации
- База данных: отсутствующие индексы, N+1, медленные JOIN. Диагностика — slow query log, APM трассировки, EXPLAIN.
- Кэши: маленький TTL, кэш‑миcсы при сериализации, избыточная инвалидация. Метрики hit/miss, размер и eviction.
- Пулы соединений: слишком маленький или большой размер пула. Признаки — очередь запросов, 5xx gateway timeout.
- Файловая система и CDN: большие изображения без оптимизации, отсутствие gzip/br, HTTP/2/3 не включен.
- Очереди/брокеры: рост лагов, backpressure. Проверьте consumer concurrency и prefetch.
- Лимиты контейнеров: cgroups throttling (CPU throttled), OOMKill. Увеличить лимиты, пересчитать запросы/лимиты в Kubernetes.
Инфраструктура и окружение: чтобы результаты были валидными
- Генератор нагрузки должен быть мощнее тестируемой системы и сидеть близко по сети (или с нужной симуляцией RTT). Для распределенных тестов — несколько генераторов за балансировщиком.
- Отключите кэш браузера/сервера, если цель — проверить бэкенд без CDN. Или наоборот — включите CDN, если тестируете реальную пользовательскую картину.
- Зафиксируйте версии: ОС, JVM/Node, фреймворки, драйверы БД, конфиги. Малые отличия дают большие дельты.
- Для прогонов в пайплайне добавьте шаги в CI/CD и храните артефакты (JTL/JSON, дашборды) — так видно регрессии.
Практические рецепты: JMeter и k6 на одном проекте
- Проектируйте сценарии в JMeter, где удобно визуально моделировать сложные пользовательские потоки, коррелировать токены и на лету валидировать ответы.
- Реплицируйте ключевые критичные эндпоинты в k6 для CI: короткие, быстрые прогоны на каждое изменение, с thresholds как «охранными формулами» SLO.
- Для стресс‑тестов используйте Throughput Shaping в JMeter, а для длительных soak — k6 с InfluxDB+Grafana, чтобы видеть деградацию памяти/ошибок на горизонте часов.
Как оформить отчет по нагрузочному тестированию
Структура отчета:
- Резюме для бизнеса: выдержали ли цели, где риски.
- Методика: окружение, сценарии, профиль нагрузки, дата/время.
- Результаты: таблицы и графики RPS, p50/p95/p99, error rate, ресурсные метрики.
- Анализ: причины узких мест, подтвержденные логами/APM/профилировщиками.
- Рекомендации: приоритеты, оценка влияния, план работ.
- Приложения: JMX/скрипты k6, конфиги, дашборды, версии.
Интеграция с процессами разработки и DevOps
- Включите быстрые нагрузочные прогоны в PR пайплайн (k6), а расширенные — по расписанию или перед релизом.
- Храните сценарии как код (IaC для тестов): версионирование, code review, параметризация через ENV.
- Комбинируйте с инфраструктурными задачами: автоскейлинг, пул соединений, лимиты ресурсов. Здесь пригодятся услуги
и
.
Когда стоит привлечь команду
- Нужны комплексные тесты со стабами интеграций, синтетическими данными и прогоном в Kubernetes.
- Требуется оптимизация БД, кэш‑стратегий, балансировщиков, CDN и CI‑пайплайна.
- В таких случаях уместно подключить команду, которая поможет выстроить процессы end‑to‑end: от сценариев до исправлений в коде и инфраструктуре. Посмотрите наши услуги по
и материалы «
» для понимания масштабирования.
Чек‑лист: провести нагрузочное тестирование без сюрпризов
- Определены бизнес‑метрики и SLO (p95, error rate, целевой RPS).
- Сформирован профиль сценариев и доли трафика.
- Тестовая среда максимально приближена к продакшену, задокументированы отличия.
- Настроены мониторинг и APM, включены логи с trace id.
- Реалистичный think time и корреляция данных (токены, ID) в сценариях.
- Прогрев кэшей перед измерениями и контроль «теплого/холодного» состояния.
- Нагрузка задается стадиями: разогрев, плато, спад; зафиксированы длительности.
- Собраны системные метрики CPU/RAM/IO/DB, а не только RPS/latency.
- Отчеты содержат распределения (percentiles), а не только средние.
- Зафиксированы версии ПО и конфиги; артефакты тестов сохранены.
Вывод
Грамотное нагрузочное тестирование — это не только цифры в отчете, но и четкий план, корректная среда, понятные метрики и связь показателей с архитектурными решениями. Начните с ключевых сценариев, подключите JMeter и k6 под разные задачи, стандартизируйте отчеты и автоматизируйте прогоны в CI. Если нужна помощь с выбором методики, настройкой инфраструктуры и внедрением улучшений — команда LightsOn поможет выстроить процесс от теста до оптимизации. Посмотрите услуги DevOps и инфраструктура и Аудит и оптимизация сайта, а также статью «Обслуживание серверов для веб‑приложений: что это и зачем бизнесу».


