Нагрузочное тестирование отвечает на вопрос, который лучше задать до рекламной кампании, а не во время неё: сколько посетителей выдержит ваш сайт, прежде чем начнёт отдавать ошибки. В этой статье — практика стресс-теста сайта тремя инструментами: простым ab (Apache Bench), быстрым wrk и сценарным k6. Разберём команды с примерами, научимся читать RPS и латентность p95/p99 и определим момент, когда оптимизация уже не помогает и пора апгрейдить тариф VPS.
Главное правило: тестируйте только свои сайты
Прежде чем запускать хоть одну команду, зафиксируем: нагрузочный тест можно направлять только на собственный сайт — или на чужой при наличии письменного разрешения владельца. Со стороны сервера-жертвы поток запросов от ab или wrk неотличим от DoS-атаки: тот же шквал соединений с одного IP. Тест чужого ресурса «просто посмотреть» — это правонарушение, жалоба вашему хостеру и блокировка сервера. У любого провайдера, включая Cheap-Host, такая активность прямо запрещена правилами.
И даже на своём проекте соблюдайте гигиену:
- предупредите коллег и не тестируйте боевой сайт в час пик — выберите ночное окно;
- если сайт за CDN или анти-DDoS-прокси, тестируйте напрямую origin-сервер, иначе получите бан своего IP и цифры прокси, а не сервера;
- включите мониторинг (htop, а лучше Grafana + Prometheus) — без графиков CPU и памяти вы увидите «сколько», но не поймёте «почему»;
- отключите на время теста уведомления мониторинга, чтобы не разбудить дежурного.
Откуда запускать нагрузку? Не с самого тестируемого сервера (генератор отберёт CPU у сайта и исказит результат) и не с домашнего Wi-Fi (узким местом станет ваш интернет). Идеальный вариант — отдельный VPS: у Cheap-Host для этого хватит NAT Pro за 199 ₽/мес (2 vCPU, 4 ГБ RAM) — исходящих соединений он генерирует достаточно, а трафик безлимитный.
Три инструмента: когда какой
| Инструмент | Что умеет | Когда использовать |
|---|---|---|
| ab (Apache Bench) | Долбит один URL, простой отчёт | Быстрая проверка за 30 секунд, «дымовой» тест |
| wrk | Многопоточный, HTTP keep-alive, перцентили | Поиск потолка RPS сервера |
| k6 | Сценарии на JavaScript, этапы нагрузки, пороги | Реалистичная имитация пользователей, регулярные тесты |
ab: быстрый тест за 30 секунд
Apache Bench входит в пакет apache2-utils:
sudo apt update
sudo apt install -y apache2-utils
ab -n 1000 -c 10 https://example.com/
Здесь -n 1000 — всего запросов, -c 10 — одновременных соединений. Ключевые строки отчёта:
Requests per second: 287.41 [#/sec] (mean)
Time per request: 34.792 [ms] (mean)
Failed requests: 0
Percentage of the requests served within a certain time (ms)
50% 31
95% 58
99% 112
Requests per second — это и есть RPS, пропускная способность. Failed requests должно быть 0: если появились ошибки, сервер уже захлёбывается. Таблица перцентилей внизу важнее среднего: строка «95% — 58 мс» означает, что 95 из 100 запросов уложились в 58 мс.
Ограничения ab: один URL, слабая работа с keep-alive (флаг -k есть, но по умолчанию выключен), однопоточность. Для серьёзной нагрузки берём wrk.
wrk: ищем потолок производительности
wrk написан на C, использует несколько потоков и событийную модель — с одной средней машины он выжимает десятки тысяч RPS. Установка на Ubuntu 24.04:
sudo apt install -y wrk
wrk -t4 -c100 -d60s --latency https://example.com/
Параметры: -t4 — 4 потока (по числу ядер генератора), -c100 — 100 открытых соединений, -d60s — минута теста, --latency — подробная статистика задержек. Пример вывода:
Running 1m test @ https://example.com/
4 threads and 100 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 45.21ms 68.34ms 1.02s 91.24%
Req/Sec 712.50 120.11 1.05k 72.00%
Latency Distribution
50% 28.15ms
75% 49.32ms
90% 98.77ms
99% 341.02ms
170514 requests in 1.00m, 2.51GB read
Requests/sec: 2841.90
Transfer/sec: 42.81MB
Методика поиска потолка: повторяйте тест, удваивая -c (50 → 100 → 200 → 400), и следите за двумя кривыми. Пока RPS растёт, а латентность стабильна — запас есть. Как только RPS упёрся в плато, а p99 полетела вверх — вы нашли предел сервера. Число до плато и есть его честная ёмкость.
k6: сценарии, похожие на живых пользователей
Реальные посетители не долбят одну страницу — они ходят по сайту с паузами. k6 описывает такое поведение скриптом на JavaScript. Установка из официального репозитория:
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | sudo tee /etc/apt/sources.list.d/k6.list
sudo apt-get update
sudo apt-get install -y k6
Сценарий load-test.js с плавным ростом до 100 виртуальных пользователей (VU) и порогами качества:
import http from "k6/http";
import { check, sleep } from "k6";
export const options = {
stages: [
{ duration: "1m", target: 20 }, // разогрев
{ duration: "3m", target: 100 }, // рост до пика
{ duration: "2m", target: 100 }, // удержание пика
{ duration: "1m", target: 0 }, // спад
],
thresholds: {
http_req_duration: ["p(95)<500"], // 95% запросов быстрее 500 мс
http_req_failed: ["rate<0.01"], // ошибок меньше 1%
},
};
export default function () {
const res = http.get("https://example.com/");
check(res, { "status 200": (r) => r.status === 200 });
sleep(Math.random() * 3 + 1); // пауза 1–4 с, как у человека
}
Запуск: k6 run load-test.js. Если пороги из thresholds нарушены, k6 завершится с ошибкой — удобно для запуска в CI: тест производительности станет таким же обязательным, как юнит-тесты. Как гонять такие проверки автоматически, мы рассказывали в статье про self-hosted runner GitHub Actions.
Как читать результаты: RPS и латентность
Две метрики описывают производительность с разных сторон:
- RPS (requests per second) — сколько запросов сервер обрабатывает в секунду. Это ёмкость: «сколько влезет».
- Латентность — сколько ждёт каждый запрос. Это качество: «насколько быстро». Смотрите на p95 и p99, а не на среднее — среднее прячет хвост медленных запросов, которые и раздражают пользователей.
Чтобы перевести RPS в посещаемость: пользователь генерирует запрос к бэкенду примерно раз в 5–10 секунд (остальное — статика и чтение). Значит, 100 стабильных RPS — это порядка 500–1000 одновременных посетителей. Ориентиры «нормы» сильно зависят от стека:
- статика через Nginx — тысячи RPS даже на младшем тарифе;
- WordPress без кеша — 10–50 RPS (каждый запрос — PHP плюс запросы к MySQL);
- WordPress с полностраничным кешем — 300–1000+ RPS;
- API на Node.js/Go с лёгкой логикой — сотни и тысячи RPS.
Здоровый результат — когда при целевой нагрузке (пиковая посещаемость × 3) ошибок нет, а p95 держится ниже 300–500 мс. Если нет — ищем узкое место.
Узкое место: оптимизировать или апгрейдить тариф
Во время теста держите открытым htop на тестируемом сервере и смотрите, что кончается первым:
- CPU в 100% на php-fpm или приложении — сначала кеширование (OPcache, Redis, полностраничный кеш), потом больше ядер;
- кончается RAM, в dmesg — OOM-killer, растёт swap — уменьшить пулы, но чаще это прямой сигнал на тариф с большей памятью;
- CPU свободен, а RPS низкий — упёрлись в лимиты конфигурации:
worker_connectionsNginx,pm.max_childrenPHP-FPM, лимиты открытых файлов. Начните с оптимизации Nginx под нагрузку; - высокий iowait — медленный диск; на NVMe-тарифах встречается редко и обычно означает неоптимальные запросы к БД.
Когда конфиги выжаты, а кеш включён, дальнейший рост даёт только железо. Признаки, что пора апгрейдить тариф: CPU стабильно выше 70% в обычные (не тестовые) пики, свободной памяти меньше 15%, p95 растёт от недели к неделе при том же трафике. Удобно, что у Cheap-Host апгрейд CPU/RAM/диска выполняется без потери данных: например, с тарифа Pro (750 ₽/мес, 12 vCPU, 16 ГБ RAM) на Ultra (1500 ₽/мес, 20 vCPU, 32 ГБ RAM, 192 ГБ NVMe) можно перейти без переустановки и переноса сайта — после апгрейда просто повторите тот же тест wrk и сравните цифры.
FAQ
Законно ли нагрузочное тестирование?
Тестировать можно только свои сайты и серверы либо чужие с письменного разрешения владельца. Нагрузочный тест чужого ресурса без согласия неотличим от DoS-атаки и влечёт ответственность, а хостинг-провайдер заблокирует сервер за такую активность.
Какой RPS считается нормальным для сайта?
Зависит от контента: статика через Nginx выдаёт тысячи RPS даже на слабом VPS, WordPress без кеша — 10–50 RPS, с кешем — сотни. Сравнивайте не с чужими цифрами, а со своей пиковой посещаемостью с запасом в 3–5 раз.
Чем отличаются ab, wrk и k6?
ab — простейший инструмент для быстрой проверки одного URL. wrk выжимает максимальную нагрузку с одной машины и точнее меряет латентность. k6 моделирует реалистичные пользовательские сценарии на JavaScript: переходы, паузы, пороги качества.
Почему важна латентность p95, а не средняя?
Среднее скрывает проблемы: при среднем 100 мс каждый двадцатый запрос может занимать 3 секунды. p95 показывает время, в которое укладываются 95% запросов, — честная оценка того, что видит реальный пользователь в худшем случае.
Откуда запускать нагрузочный тест — с сервера или со своей машины?
Лучше с отдельного VPS в другой сети: тест с самого сервера не учитывает сеть и отбирает CPU у сайта, а домашний интернет сам станет узким местом. Дешёвый NAT VPS за 59–199 ₽/мес — подходящая машина-генератор нагрузки.
Вывод
Нагрузочное тестирование — это полчаса работы, которые страхуют от худшего сценария: сайт падает ровно в момент, когда на него пришёл трафик. Схема простая: быстрый прогон ab, поиск потолка wrk, реалистичный сценарий k6 — и решение по фактам: тюнить конфиги, включать кеш или брать тариф мощнее. Если текущий сервер потолок уже показал — у Cheap-Host тариф Pro за 750 ₽/мес (12 vCPU, 16 ГБ RAM, 128 ГБ NVMe) с апгрейдом до Ultra без потери данных: KVM, безлимитный трафик, выдача за минуту. Тарифы — на cheap-host.onl.