Разработка нагрузочных тестов для сайта (k6)
k6 — современный инструмент нагрузочного тестирования от Grafana Labs. Сценарии на JavaScript, встроенные метрики, интеграция с Grafana/InfluxDB. Оптимален для API-нагрузки и проверки performance SLA.
Установка
# Windows
winget install k6
# macOS
brew install k6
# Linux
sudo apt install k6
Базовый сценарий
// scripts/smoke-test.js
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate } from 'k6/metrics';
const errorRate = new Rate('error_rate');
export const options = {
vus: 10, // 10 виртуальных пользователей
duration: '30s', // в течение 30 секунд
thresholds: {
http_req_duration: ['p(95)<500'], // 95% запросов быстрее 500мс
http_req_failed: ['rate<0.01'], // менее 1% ошибок
error_rate: ['rate<0.05'],
},
};
export default function () {
const res = http.get('https://staging.example.com/api/products');
const ok = check(res, {
'status is 200': r => r.status === 200,
'response time < 500ms': r => r.timings.duration < 500,
'has data array': r => r.json('data') !== undefined,
});
errorRate.add(!ok);
sleep(1);
}
Ramping-сценарий (нарастающая нагрузка)
export const options = {
stages: [
{ duration: '2m', target: 10 }, // разогрев: 0→10 VU за 2 минуты
{ duration: '5m', target: 10 }, // выдержка: 10 VU 5 минут
{ duration: '2m', target: 50 }, // рост до 50 VU
{ duration: '5m', target: 50 }, // выдержка: 50 VU 5 минут
{ duration: '2m', target: 100 }, // пиковая нагрузка
{ duration: '5m', target: 100 },
{ duration: '2m', target: 0 }, // откат
],
thresholds: {
http_req_duration: ['p(99)<2000'],
http_req_failed: ['rate<0.02'],
},
};
Сценарий с авторизацией
import http from 'k6/http';
import { check, group, sleep } from 'k6';
import { SharedArray } from 'k6/data';
// Загрузить тестовых пользователей из файла
const users = new SharedArray('users', () =>
JSON.parse(open('./data/users.json'))
);
export default function () {
const user = users[Math.floor(Math.random() * users.length)];
// Логин
let loginRes;
group('Login', () => {
loginRes = http.post('https://staging.example.com/api/auth/login',
JSON.stringify({ email: user.email, password: user.password }),
{ headers: { 'Content-Type': 'application/json' } }
);
check(loginRes, {
'login successful': r => r.status === 200,
'token received': r => r.json('access_token') !== undefined,
});
});
const token = loginRes.json('access_token');
const headers = { Authorization: `Bearer ${token}` };
sleep(1);
// Просмотр продуктов
group('Browse Products', () => {
const res = http.get('https://staging.example.com/api/products?page=1', { headers });
check(res, { 'products loaded': r => r.status === 200 });
sleep(2);
});
// Оформление заказа
group('Create Order', () => {
const res = http.post('https://staging.example.com/api/orders',
JSON.stringify({ product_id: 1, quantity: 1 }),
{ headers: { ...headers, 'Content-Type': 'application/json' } }
);
check(res, { 'order created': r => r.status === 201 });
});
sleep(1);
}
Вывод метрик в Grafana
# InfluxDB + Grafana
k6 run --out influxdb=http://localhost:8086/k6 script.js
# k6 Cloud
k6 cloud script.js
# Grafana Cloud k6
K6_CLOUD_TOKEN=xxx k6 run --out cloud script.js
Интерпретация результатов
/\ |‾‾| /‾‾/ /‾‾/
/\ / \ | |/ / / /
/ \/ \ | ( / ‾‾\
/ \ | |\ \ | (‾) |
/ __________ \ |__| \__\ \_____/
execution: local
script: script.js
output: -
scenarios: (100.00%) 1 scenario, 100 max VUs, 10m30s max duration
✓ http_req_duration.............: avg=132ms min=45ms med=112ms max=1.2s p(90)=245ms p(95)=380ms
✓ http_req_failed...............: 0.12% ✓ 4 / ✗ 3312
✗ http_req_duration{p(99)}......: avg=980ms min=780ms — превысило 2000ms порог
Срок реализации
Базовый набор нагрузочных сценариев (smoke, load, stress, soak): 3–5 дней.







