k6: нагрузочное тестирование как система
9 / 1753%
Метрики, checks и thresholds, привязанные к бизнес-целям
25 минут
Основные метрики k6 (core)
http_req_duration— total время запроса (wait + connect + tls + send + receive).http_req_waiting— время ответа сервера (TTFB), главный кандидат на анализ.http_req_failed— доля ошибок (network + HTTP 4xx/5xx).checks— доля пройденных проверок.vus,iterations,dropped_iterations— здоровье генератора.
Trend vs Rate vs Gauge
- Trend — распределение значений (min/avg/p95/p99). Используйте для latency, размеров payload, времени бизнес-операции.
- Rate — доля успехов/ошибок (0..1). Используйте для error rate, фейлов платежей.
- Gauge — текущее значение (последнее измерение). Используйте для счётчиков активных VU или размеров очередей, которые вы сами публикуете.
Checks и thresholds на примере checkout
// metrics.js
import http from "k6/http";
import { check, Trend, Rate } from "k6";
const checkoutLatency = new Trend("checkout_latency");
const checkoutErrors = new Rate("checkout_errors");
export const options = {
scenarios: {
checkout: {
executor: "constant-arrival-rate",
rate: 120,
timeUnit: "1s",
preAllocatedVUs: 20,
maxVUs: 150,
duration: "20m",
exec: "checkoutFlow",
tags: { flow: "checkout" },
},
},
thresholds: {
http_req_duration: ["p(95)<600", "p(99)<1000"], // один массив, без дубликатов ключа
http_req_failed: ["rate<0.01"],
"checks{flow:checkout}": ["rate>0.97"],
checkout_latency: ["p(95)<550"],
checkout_errors: ["rate<0.02"],
},
};
export function checkoutFlow() {
const res = http.post(`${__ENV.BASE_URL}/api/checkout`, { payment: "test" });
checkoutLatency.add(res.timings.duration, res.tags);
checkoutErrors.add(res.status >= 500 || res.status === 0);
check(res, {
"status 200": (r) => r.status === 200,
"pays fast": (r) => r.timings.waiting < 500,
});
}abortOnFail: true в threshold — спасение для CI: если SLO нарушено, тест
сразу падает и не тратит время. Но применяйте осторожно для soak-тестов, где
важна динамика во времени.
Привязка к SLO/Error Budget
- SLO: p95 < 600ms при 120 rps, error rate < 1%. В thresholds — именно эти числа.
- Error budget: 1% ошибок → за 20 минут теста допустимо ~144 ошибки. Если превышаем — рекомендации: профайлинг/отложить релиз.
- Отчет: «p95 540ms (-5% к baseline), error rate 0.6% (бюджет не сожжен),
http_req_waitingрастет параллельно latency БД → узкое место — БД».
Теги для выборочного анализа
- Добавляйте
tagsв сценарии и запросы:group,flow,endpoint,release. - Анализируйте:
http_req_duration{flow:buyer}илиchecks{endpoint:/api/cart}. - В Grafana/Prometheus эти теги позволяют быстро фильтровать проблемные флоу.
Resilience: стресс, спайк и восстановление
- Stress/Breakpoint: плавно растем до отказа, фиксируем точку деградации (p99, error rate, saturation CPU/RAM/DB). В отчет — «ломается на 650 rps, p99=1.8s, ошибки 3%».
- Spike: резкий скачок x2–x3 к целевому RPS, смотрим, справляются ли очереди/кэш и как быстро восстанавливается латентность.
- Recovery: после плато снижаем нагрузку и проверяем, возвращается ли система к baseline (длина очередей, GC, connection pool).
- Для стресс-фазы thresholds можно смягчать, но точку отказа фиксируйте и превращайте в capacity план.
Бизнес-метрики как кастомные метрики
- Считайте domain KPI прямо в тесте:
orders_per_minute,successful_payments,cart_abandon_rate,order_value. - Пример:
import { Rate, Counter, Trend } from "k6/metrics";
const orders = new Counter("orders_total");
const paymentFail = new Rate("payment_fail_rate");
const orderValue = new Trend("order_value");
export function checkoutFlow() {
const res = http.post(`${__ENV.BASE_URL}/api/checkout`, { payment: "test" });
const ok = res.status === 200;
orders.add(ok ? 1 : 0, res.tags);
paymentFail.add(!ok, res.tags);
if (ok) {
orderValue.add(res.json("amount") || 0, res.tags);
}
}- Thresholds по бизнес-метрикам ближе к деньгам, чем «просто p95»:
payment_fail_rate: ["rate<0.01"], стабильный ростorders_total,order_value: ["p(95)>40"]для среднего чека.
✅ Чек-лист завершения урока
После этого урока вы должны уметь:
Основные метрики:
- Понимать разницу между
http_req_durationиhttp_req_waiting - Знать, что такое
http_req_failedи как его интерпретировать - Понимать типы метрик: Trend (p95/p99), Rate (error rate), Gauge (VUs)
Checks и thresholds:
- Создавать checks для проверки корректности ответов
- Настраивать thresholds привязанные к SLO:
p(95)<600,rate<0.01 - Использовать
abortOnFail: trueдля критичных метрик - Избегать дубликатов ключей в thresholds (один массив на метрику!)
Кастомные метрики:
- Создавать Trend для бизнес-операций:
checkout_latency - Создавать Rate для ошибок:
checkout_errors - Создавать Counter для подсчетов:
orders_total - Добавлять tags к метрикам для фильтрации
Привязка к бизнесу:
- Переводить SLO в thresholds: "p95<600ms при 120 RPS" →
http_req_duration: ["p(95)<600"] - Рассчитывать error budget: 1% за тест = ~144 ошибки за 20 минут
- Создавать бизнес-метрики:
payment_fail_rate,order_value,cart_abandon_rate
Теги для анализа:
- Добавлять tags в scenarios:
{ flow: 'checkout' } - Использовать tags в thresholds:
checks{flow:checkout} - Фильтровать метрики по тегам в Grafana/Prometheus
Практическое задание:
- Добавьте кастомную метрику для вашего критичного user journey
- Настройте thresholds привязанные к вашим SLO
- Добавьте бизнес-метрику (например, успешных транзакций в минуту)
- Запустите тест и проверьте, что thresholds работают (тест падает при нарушении)
Если чек-лист пройден — переходите к уроку 10: изучим custom метрики и результаты и триангулировать проблемы.