Что такое нагрузочное тестирование? Какие инструменты используются?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Нагрузочное тестирование (Load Testing)
Нагрузочное тестирование — это вид тестирования производительности, при котором система подвергается постепенно возрастающей нагрузке, чтобы определить, насколько хорошо она справляется при нормальных и повышенных условиях использования. Это критично для того, чтобы гарантировать, что приложение не упадёт, когда на него наваливается множество пользователей.
Почему это важно
Реальные сценарии:
- Чёрная пятница: в интернет-магазин одновременно заходит в 100 раз больше пользователей
- Спортивные события: миллионы людей пытаются купить билеты одновременно
- Вирусный контент: социальная сеть получает неожиданный взрыв трафика
Без нагрузочного тестирования: приложение может упасть при пике нагрузки, потеряются пользователи и деньги.
Виды нагрузочного тестирования
1. Load Testing (линейное увеличение нагрузки)
Суть: постепенно добавляем пользователей до момента, когда система начинает критически деградировать.
Профиль нагрузки:
Пользователей (Y)
|
1000| _____ (система перегружена)
| __/
| __/
| __/
500| __/
| /
|/_________________ Время (X)
0 10 20 30 40 мин
0 мин: 1 пользователь
10 мин: 250 пользователей
20 мин: 500 пользователей
30 мин: 750 пользователей
40 мин: 1000 пользователей
Цель: найти точку, где система начинает задыхаться.
2. Stress Testing (критическая нагрузка)
Суть: загружаем систему БЕЗ предела, пока она полностью не упадёт.
Вопросы, на которые отвечает Stress Testing:
- Что происходит с данными при краше системы?
- Теряются ли транзакции?
- Может ли система восстановиться автоматически?
3. Spike Testing (скачок нагрузки)
Суть: внезапно прыгает нагрузка, без постепенного увеличения.
Профиль:
1000 пользователей
↑
| ________
|_| |
0| |________ Время
Сценарий: рассылка письма с уникальной ссылкой → все пользователи заходят в 5 минут одновременно.
4. Soak Testing (продолжительная нагрузка)
Суть: держим систему под постоянной умеренной нагрузкой в течение длительного времени.
Цель: найти утечки памяти, проблемы с кешем, накопление данных.
Пример:
- 500 одновременных пользователей
- 24 часа нонстоп
- Ищем, когда начнёт падать производительность
Метрики нагрузочного тестирования
1. Response Time (время ответа)
- Average response time: средний ответ, например 200ms
- Percentile 95 (p95): 95% запросов ответили быстрее, чем X ms (обычно критичнее, чем average)
- Max response time: самый долгий запрос
2. Throughput (пропускная способность)
- Количество запросов в секунду (RPS — Requests Per Second)
- Количество транзакций в секунду (TPS)
- Килобайты в секунду (Mbps)
Пример: при 1000 пользователей система обрабатывает 5000 RPS.
3. Error Rate (процент ошибок)
- Обычно при нормальной нагрузке: 0% (или < 0.1%)
- При стресс-тестировании может увеличиться до 10-50%
4. CPU, Memory, Disk usage
- CPU: обычно 70-80% нормально, > 90% — перегруз
- Memory: утечки памяти видны по графику (должна быть стабильна)
- Disk I/O: как часто система пишет на диск
5. Database connections
- Количество открытых подключений к БД
- Connection pool exhaustion (кончились свободные подключения)
Инструменты для нагрузочного тестирования
1. Apache JMeter (классический, открытый исходный код)
Плюсы:
- Бесплатный
- Старый и стабильный
- Поддерживает множество протоколов (HTTP, FTP, JDBC, SOAP)
- Можно писать код на Java
Минусы:
- Медленный
- Требует Java
- UI немного устаревший
Пример скрипта:
// Создаём 100 потоков (пользователей)
// Каждый делает 10 запросов
// На сервер https://api.example.com
// Это даст нам 1000 запросов всего
2. Gatling (современный, на Scala/Java)
Плюсы:
- Язык, который понятен разработчикам
- Хорошие отчёты
- Быстрый
- Может генерировать высокие нагрузки (миллионы RPS)
Пример скрипта:
scenario("My Scenario")
.repeat(100) {
exec(http("Get Users").get("/api/users"))
}
3. Locust (Python-based, простой)
Плюсы:
- Python (много QA знают Python)
- Простой для написания тестов
- Web UI для управления нагрузкой
Минусы:
- Медленнее чем Gatling
- Сложнее масштабировать на миллионы пользователей
Пример:
class User(HttpUser):
@task
def get_users(self):
self.client.get("/api/users")
4. k6 (современный, JavaScript)
Плюсы:
- JavaScript (разработчики его знают)
- Облачное исполнение (SaaS)
- Хорошая интеграция с CI/CD
- Быстрый
Минусы:
- Freemium модель
Пример:
import http from 'k6/http';
export default function() {
http.get('https://httpbin.org/delay/0');
}
export let options = {
vus: 100, // 100 виртуальных пользователей
duration: '30s',
};
5. Wrk (высокопроизводительный, C)
Плюсы:
- Очень быстрый
- Минимальные ресурсы
- Хорошо для стресс-тестирования
Минусы:
- Только HTTP
- Сложнее сценарии
Использование:
wrk -t12 -c400 -d30s http://example.com
# -t12: 12 потоков
# -c400: 400 одновременных соединений
# -d30s: тест 30 секунд
6. Artillery (Node.js, простой)
Пример:
config:
target: 'https://api.example.com'
phases:
- duration: 60
arrivalRate: 10 # 10 пользователей в секунду
- duration: 120
arrivalRate: 30
scenarios:
- name: 'Get Users'
flow:
- get:
url: '/api/users'
Процесс нагрузочного тестирования
Шаг 1: Определить базовые характеристики
Нормальная нагрузка: 500 одновременных пользователей
Пиковая нагрузка: 5000 одновременных пользователей
Критическая нагрузка: 10000+ одновременных пользователей
Шаг 2: Создать тестовый сценарий
Пользователь:
1. Заходит на главную страницу
2. Ищет товар
3. Добавляет в корзину
4. Оформляет покупку
Шаг 3: Запустить тест
Время | Пользователи | Avg RT | P95 RT | Errors
0:00 | 0 | - | - | 0%
5:00 | 500 | 200ms | 400ms | 0%
10:00 | 2000 | 400ms | 800ms | 0.1%
15:00 | 5000 | 1500ms | 3000ms | 5%
20:00 | 10000 | 5000ms | 9000ms | 25%
Шаг 4: Анализировать результаты
- При 5000 пользователей — приемлемая производительность
- При 10000 — система начинает задыхаться
- Вывод: при 7000 одновременных пользователей нужна оптимизация
Практические примеры
Пример 1: k6 для API нагрузочного тестирования
import http from 'k6/http';
import { check } from 'k6';
export let options = {
stages: [
{ duration: '5m', target: 100 }, // Нарастаем до 100 пользователей за 5 минут
{ duration: '10m', target: 100 }, // Держим 100 пользователей 10 минут
{ duration: '5m', target: 0 }, // Убываем 5 минут
],
};
export default function() {
let response = http.get('https://api.example.com/users');
check(response, {
'is status 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
});
}
Пример 2: Проверка утечки памяти (Soak Testing)
// Держим 500 пользователей в течение 24 часов
// Смотрим, падает ли производительность
export let options = {
stages: [
{ duration: '10m', target: 500 },
{ duration: '1430m', target: 500 }, // 24 часа - 10 минут
],
};
Интеграция с CI/CD
GitHub Actions пример:
name: Load Test
on: push
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run k6 load test
run: k6 run loadtest.js
Заключение
Нагрузочное тестирование — это не опция, а обязательность для:
- Web приложений, где ценится uptime
- E-commerce сайтов (особенно перед распродажами)
- Социальных сетей
- Финансовых систем
Без нагрузочного тестирования вы слепо идёте в production, не зная, выдержит ли ваша система реальную нагрузку. Даже если функционально всё работает, при 10000 одновременных пользователей система может упасть за секунду.