Skip to main content
Back to course
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 метрики и результаты и триангулировать проблемы.

Метрики, checks и thresholds, привязанные к бизнес-целям — k6: нагрузочное тестирование как система — Potapov.me