Нагрузочный тест API с k6: какой VPS выбрать перед запуском рекламы
Рекламный кабинет обещает посетителей. Разработчик обещает, что сайт работает. Сервер пока ничего не обещает: его никто не спросил, что произойдёт, когда карточки товаров начнут открывать одновременно. Нагрузочный тест позволяет провести этот разговор заранее, в спокойной обстановке и на копии приложения.
Нам нужен ответ на конкретный вопрос: выдерживает ли выбранная конфигурация ожидаемый поток запросов с приемлемой задержкой и без ошибок. Для этого достаточно отдельного генератора нагрузки, реалистичного сценария и нескольких одинаковых прогонов. Красивое число «запросов в секунду» без этих условий почти бесполезно при выборе тарифа.
Содержание
Подберите VPS по результатам своего теста
Разместите генератор нагрузки отдельно от приложения. Uab Start или Heka Standard могут стать начальной конфигурацией тестового стенда; окончательный выбор делайте по измерениям своего API.
Сравнить конфигурации VPSНачинаем с поведения покупателя
Человек, пришедший по рекламе, не обновляет главную страницу двадцать раз в секунду. Он открывает каталог, выбирает фильтр, смотрит товар и иногда переходит к оформлению. Эти действия нагружают разные части системы. Главная может целиком возвращаться из кеша, а поиск каждый раз обращаться к базе.
Возьмите обезличенную статистику своего приложения или составьте небольшую учебную модель. Например, большинство обращений приходится на каталог, часть — на карточки, меньшая доля — на поиск. Проценты задавайте по своему проекту. Если данных ещё нет, запишите предположения в протокол теста, чтобы через месяц не принять их за наблюдения реальных покупателей.
Отдельно перечислите операции с последствиями: создание заказов, отправку писем, списание бонусов, запросы к платному API. Их проверяют в тестовом окружении с учебными аккаунтами и отключёнными внешними действиями. Настоящую оплату нельзя превращать в расходный материал нагрузочного эксперимента. Для первого запуска выберем чтение каталога: его проще сделать безопасным и проверить содержимое ответа.
Две машины и один понятный стенд
Приложение и генератор нагрузки лучше разместить на разных VPS. Иначе они начнут бороться за процессор, память и сетевые ресурсы одной машины, а измерение покажет странную смесь производительности сайта и самого теста. У генератора тоже есть предел; за его загрузкой необходимо наблюдать.
На целевом сервере подготовьте копию приложения с теми же версиями зависимостей, конфигурацией базы и способом запуска, которые планируются после рекламы. Объём данных должен быть похож на будущий рабочий: поиск по ста товарам и по ста тысячам может вести себя совершенно по-разному. Персональные сведения в тестовую базу переносить не требуется.
Оставьте постоянными регион генератора, регион приложения и сетевой путь. Если в одном прогоне запросы шли через CDN, а в другом напрямую к серверу, сравнение уже отвечает на другой вопрос. Полезно провести два отдельных эксперимента: пользовательский путь целиком и прямую нагрузку на собственный backend. Для каждого сохраняйте свой адрес и набор условий.
Для пилота небольшого API на MAATRIX можно начать с Uab Start — 2 vCPU и 4 GB RAM. Если на той же машине находятся база, несколько обработчиков и тяжёлое приложение, для первой проверки удобнее Heka Standard — 4 vCPU и 8 GB. Это кандидаты для измерений. Само название тарифа не сообщает, сколько посетителей выдержит код.
Первый сценарий k6
k6 запускает сценарии на JavaScript и собирает метрики запросов. Устанавливайте инструмент по официальной инструкции запуска; для Docker доступен образ grafana/k6. В повторяемом испытании зафиксируйте версию образа, чтобы обновление инструмента не меняло условия между прогонами.
Ниже сценарий для учебного контракта API: GET /api/products?limit=10 должен возвращать код 200 и JSON с массивом items. Путь и проверку структуры замените на контракт собственного приложения. Домен api.example.com — пример, запускать тест нужно только против своего разрешённого стенда.
import http from 'k6/http';
import { check, sleep } from 'k6';
if (!__ENV.BASE_URL) throw new Error('Set BASE_URL for your test environment');
const base = __ENV.BASE_URL.replace(/\/$/, '');
export const options = {
vus: 1,
duration: '30s',
thresholds: {
http_req_failed: ['rate<0.01'],
checks: ['rate>0.99'],
http_req_duration: ['p(95)<500'],
},
};
export default function () {
const response = http.get(`${base}/api/products?limit=10`, {
timeout: '10s',
tags: { endpoint: 'catalog' },
});
let valid = false;
try { valid = Array.isArray(response.json().items); } catch (_) {}
check(response, {
'catalog HTTP 200': (r) => r.status === 200,
'catalog contains items': () => valid,
});
sleep(1);
}
Сохраните файл как catalog.js и выполните короткий пробный запуск:
k6 run -e BASE_URL=https://api.example.com catalog.js
Сначала убедитесь, что все проверки проходят при одном виртуальном пользователе. Если тест ждёт поле items, а приложение возвращает products, увеличение нагрузки ничего не прояснит. Так же необходимо обнаружить неожиданный редирект на страницу входа: быстрый HTML с формой авторизации ещё не означает, что каталог выдержал испытание.
Порог 500 миллисекунд и допустимая доля ошибок в примере — выбранные учебные требования. Замените их условиями своего сервиса. Проверки check оценивают ответы, а thresholds определяют, считается ли весь прогон успешным; механизм описан в документации k6 о порогах.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
АРЕНДОВАТЬ СЕРВЕРПовышаем нагрузку ступенями
После исправного пробного запуска повторите сценарий с пятью виртуальными пользователями, затем с десятью. Дайте каждой ступени поработать несколько минут. Для смены параметров можно использовать аргументы запуска:
k6 run --vus 5 --duration 3m -e BASE_URL=https://api.example.com catalog.js
Перед увеличением нагрузки заранее определите условия остановки: длительный рост ошибок, заполнение диска, исчерпание памяти, потерю доступа к стенду. Оператор должен иметь отдельную административную сессию и возможность остановить генератор. Проверять предел системы до полной недоступности полезно только в специально запланированном эксперименте.
Виртуальные пользователи в этом сценарии ждут завершения запроса и затем делают паузу. Когда сервер замедляется, они начинают отправлять меньше запросов. Для моделирования рекламы с заданным потоком новых обращений позже понадобится сценарий с постоянной или меняющейся интенсивностью поступления. Разницу между этими моделями объясняет руководство k6. Нельзя автоматически переводить десять VU в десять посетителей сайта или фиксированное число запросов в секунду.
Добавляйте разные товары и варианты поиска из подготовленного набора данных. Постоянное обращение к одному объекту может проверить в основном горячий кеш. При этом полностью случайные бессмысленные параметры тоже искажают картину: они создают нагрузку, которой у настоящих покупателей не будет.
Что смотреть одновременно с отчётом
Запишите долю ошибок, длительность ответов, достигнутую интенсивность запросов и результат содержательных проверок. На сервере наблюдайте CPU, память, подкачку, дисковые операции, число соединений с базой и очередь фоновых задач. Средняя загрузка процессора сама по себе не объясняет, почему покупатель ждал товар пять секунд.
Условный пример интерпретации: CPU свободен, а запросы к базе ждут блокировку. Увеличение числа ядер не обязательно устранит задержку. Другой вариант: приложение удерживает большие объекты, память заканчивается и начинается активная подкачка. Здесь нужно изучить расход памяти и код; переход на более вместительную конфигурацию может дать запас, но не исправит бесконечный рост.
Отдельно следите за ответами 429. Они могут означать исправно работающий ограничитель частоты, а не недостаток VPS. Тайм-аут внешнего API тоже нельзя честно записать в «слабый процессор». В отчёте полезно разделить собственную инфраструктуру и внешние зависимости.
Сравниваем тарифы без самообмана
До сравнения полезно перевести рекламный прогноз в понятную модель. Допустим, в учебном расчёте ожидается три тысячи посещений за десять минут. Это в среднем пять новых посещений в секунду, но никак не пять запросов: одна страница может обращаться к нескольким API. Если каждый визит даёт четыре обращения к вашему backend, исходная оценка составит двадцать запросов в секунду. Это только арифметический пример. В реальном плане учитывайте распределение по времени, повторные действия и то, какая часть запросов обслуживается кешем.
Теперь посмотрите на хвост задержек. Среднее значение способно выглядеть прилично, пока небольшая группа покупателей ждёт гораздо дольше остальных. Показатель p95 отделяет самые медленные пять процентов измерений от остальных; он помогает заметить проблему, но не объясняет её причину. Сопоставляйте время медленных ответов с запросами к базе и журналами приложения. Если неприятности начинаются только при определённом фильтре каталога, общий график сайта будет слишком грубым инструментом.
Отмечайте и время восстановления после завершения нагрузки. Очередь может продолжать обрабатывать задания, хотя посетителей уже нет. Сервер, который быстро ответил во время короткого теста, но затем десять минут разгребает последствия, требует другого запаса ресурсов и ограничения приёма задач. Для магазина это влияет на письма, обновление остатков и уведомления менеджеру.
Сохраните версию приложения, размер базы, настройки кеша, команду запуска, время теста и его длительность. После изменения конфигурации повторите тот же сценарий. Проведите несколько прогонов: один удачный результат способен оказаться случайностью, особенно при меняющейся внешней нагрузке.
| Конфигурация | Нагрузка | p95 ответа | Ошибки | CPU и память | Ограничение |
|---|---|---|---|---|---|
| Первый VPS | Заполнить после теста | Измерить | Измерить | Измерить | Найти причину |
| Второй VPS | Тот же сценарий | Измерить | Измерить | Измерить | Сравнить |
Оставьте запас для фоновых задач, обновлений, роста базы и неравномерного потока. Не выбирайте тариф, который проходит тест только в последнюю секунду перед исчерпанием памяти. С другой стороны, нет смысла автоматически покупать самый большой VPS, если узкое место находится в одном неоптимальном запросе.
В тарифах MAATRIX можно подобрать отдельный сервер для стенда и конфигурацию для приложения. Главный результат работы — сохранённый сценарий, который вы сможете повторить после изменения кода. Через несколько релизов он окажется ценнее первой таблицы: реклама меняется, база растёт, а проверка остаётся понятным способом увидеть предел заранее.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
АРЕНДОВАТЬ СЕРВЕРОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →