Почему тестирование производительности важно

Функциональная корректность недостаточна. Приложение, работающее для одного пользователя, но падающее при 100 одновременных — провальный продукт.

Реальные последствия:

  • Amazon: каждые 100мс задержки стоили 1% продаж
  • Google: задержка 0.5 секунды в поиске — минус 20% трафика
  • 1 секунда задержки загрузки снижает конверсии на 7%
  • 40% пользователей уходят с сайта, загружающегося дольше 3 секунд

Типы тестирования производительности

Нагрузочное тестирование (Load Testing)

Проверяет приемлемую работу при ожидаемой нормальной нагрузке.

Пример: Сайт ожидает 5,000 одновременных пользователей. Симулируем 5,000 с типичными действиями и проверяем — время отклика менее 2 секунд, ошибки менее 1%.

Стресс-тестирование (Stress Testing)

Выводит систему за пределы ожидаемой ёмкости для поиска точек отказа.

Пример: Постепенно увеличиваем с 5,000 до 50,000. Когда время отклика превышает 10 секунд? Когда начинаются ошибки? Система падает или деградирует плавно?

Тестирование на выносливость (Endurance/Soak)

Запускает под устойчивой нагрузкой на длительный период (часы, дни) для обнаружения проблем, проявляющихся со временем.

Пример: 5,000 пользователей в течение 72 часов. Память стабильна или растёт? Время отклика деградирует?

Spike-тестирование

Применяет внезапные экстремальные скачки нагрузки.

Пример: Нормально 5,000. Внезапный скачок до 50,000 на 5 минут (флэш-распродажа), возврат к 5,000. Система выживает? Как быстро восстанавливается?

Объёмное тестирование (Volume Testing)

Оценивает поведение с большими объёмами данных — миллионами записей, гигабайтами файлов.

Пример: 10 миллионов пользователей и 50 миллионов транзакций в БД. Поисковые запросы всё ещё за 2 секунды?

Тестирование масштабируемости (Scalability)

Как хорошо система масштабируется при добавлении ресурсов. 2x серверов = 2x ёмкости?

Тестирование ёмкости (Capacity)

Определяет максимальное количество пользователей/транзакций при соблюдении критериев.

Типы на диаграмме

graph TB subgraph "Нормальная работа" LOAD[Нагрузочное
Ожидаемые пользователи
Нормальные условия] ENDURANCE[На выносливость
Устойчивая нагрузка
Часы/Дни] end subgraph "За пределами нормы" STRESS[Стресс-тестирование
За пределами ёмкости
Точка отказа] SPIKE[Spike-тестирование
Внезапный всплеск
Флэш-распродажа] end subgraph "Данные и масштаб" VOLUME[Объёмное
Большие данные
Миллионы записей] SCALE[Масштабируемость
Добавление ресурсов
Линейный рост?] CAPACITY[Ёмкость
Максимум пользователей
Предел инфраструктуры] end style LOAD fill:#22c55e,color:#000 style ENDURANCE fill:#84cc16,color:#000 style STRESS fill:#f97316,color:#000 style SPIKE fill:#ef4444,color:#000 style VOLUME fill:#eab308,color:#000 style SCALE fill:#06b6d4,color:#000 style CAPACITY fill:#8b5cf6,color:#000

Ключевые метрики

Время отклика

  • Среднее: Среднее по всем запросам
  • P95: 95% запросов быстрее этого значения
  • P99: 99% быстрее. Показывает опыт самых медленных пользователей
  • Максимум: Самый медленный отдельный запрос

P95 и P99 полезнее среднего — среднее 200мс при P99 в 15 секунд означает, что 1% пользователей ждут 15 секунд.

Пропускная способность (Throughput)

Запросы/транзакции в секунду (RPS/TPS).

Частота ошибок

  • Приемлемо: < 0.1% при нормальной нагрузке
  • Тревожно: 0.1% - 1% — расследовать
  • Критично: > 1% — система отказывает

Утилизация ресурсов

  • CPU: > 80% устойчиво — предупреждение
  • Память: Постепенный рост — утечки памяти
  • Диск I/O: Высокие задержки — узкое место хранилища
  • Сеть: Приближение к лимитам — нужна CDN или оптимизация

Процесс

  1. Определить требования — Цели (отклик < 2с, throughput > 500 TPS)
  2. Определить сценарии — Какие действия симулировать
  3. Подготовить окружение — Подобие продакшена по железу и данным
  4. Создать скрипты — Автоматизировать (k6, JMeter, Gatling, Locust)
  5. Выполнить — Прогрессивная нагрузка: 10%, 25%, 50%, 75%, 100%
  6. Мониторить — Метрики приложения, сервера, БД, сети
  7. Анализировать — Сравнить с требованиями, найти узкие места
  8. Отчитаться и оптимизировать — Рекомендации, повторное тестирование

Упражнение: Определите сценарии тестирования производительности

Вы QA Lead социальной платформы:

  • 2 млн зарегистрированных, 200,000 DAU
  • Пик: 50,000 одновременных (вечером)
  • Действия: лента, публикации, фото, сообщения, поиск
  • Инфраструктура: 4 app-сервера, 2 DB-сервера, CDN
  • SLA: загрузка < 3с, API < 500мс, 99.9% uptime

Спроектируйте сценарии load, stress, endurance и spike. Для каждого: тип, профиль нагрузки, длительность, метрики.

ПодсказкаСопоставьте каждый тип с реальным сценарием. Load = нормальный вечерний пик. Stress = вирусное событие. Endurance = устойчивая нагрузка на выходных. Spike = вирусный пост знаменитости.
Решение

1. Нагрузочный тест: Нормальный вечерний пик

  • 50,000 пользователей: 60% лента, 20% публикации, 10% фото, 5% сообщения, 5% поиск
  • Длительность: 1 час
  • Метрики: Лента < 3с (P95), публикация < 500мс, загрузка фото < 5с, поиск < 1с, ошибки < 0.1%, CPU < 70%

2. Стресс-тест: Вирусное событие

  • Рампа с 50,000 до 200,000 за 30 минут
  • Длительность: 30 мин рампа + 30 мин устойчиво + 30 мин охлаждение
  • Метрики: Точка деградации, начало ошибок, поведение при отказе или плавная деградация, автоскейлинг, время восстановления

3. Тест на выносливость: Выходные

  • 30,000 пользователей устойчиво 48 часов
  • Метрики: Тренд памяти (должен быть стабильным), тренд времени отклика, пул подключений БД, рост логов, паузы GC, частота ошибок во времени

4. Spike-тест: Вирусный пост

  • База: 30,000 → Скачок: 150,000 за 2 мин → 5 мин устойчиво → Возврат за 3 мин
  • Длительность: 15 мин
  • Метрики: Отклик при скачке (допустимо до 5с), ошибки (до 2%), глубина очереди, восстановление за 5 мин

5. Объёмный тест: Рост БД

  • 50 млн публикаций, 500 млн комментариев, 200 млн фото, 2 млрд элементов ленты
  • 50,000 пользователей
  • Метрики: Генерация ленты, производительность поиска, планы выполнения запросов, I/O хранилища

Инструменты

ИнструментЯзыкЛучше дляOpen Source
k6JavaScriptСовременное API и нагрузочноеДа
JMeterJava/GUIПротокольное, enterpriseДа
GatlingScalaВысокопроизводительная симуляцияДа
LocustPythonРаспределённое, code-firstДа
ArtilleryJavaScriptБыстрое API-тестированиеДа (core)

Профессиональные советы

Совет 1: Тестируйте в окружении, подобном продакшену. Результаты с ноутбука разработчика бессмысленны. Используйте сопоставимое железо, объёмы данных и сетевую конфигурацию.

Совет 2: Мониторьте всё. Не только метрики приложения. CPU/память серверов, запросы БД, сетевая задержка, попадания в кэш CDN, время отклика внешних сервисов.

Совет 3: Установите baseline перед оптимизацией. Запустите тесты производительности до внесения изменений. Без baseline невозможно измерить, улучшила ли оптимизация что-либо.

Ключевые выводы

  • Семь типов: нагрузочное, стрессовое, на выносливость, spike, объёмное, масштабируемость, ёмкость
  • Каждый тип отвечает на свой вопрос о поведении под нагрузкой
  • Ключевые метрики: время отклика (особенно P95/P99), пропускная способность, частота ошибок, утилизация ресурсов
  • Требует окружения, подобного продакшену, и реалистичных данных
  • Тестировать перед крупными релизами, ожидаемыми пиками и изменениями архитектуры
  • Мониторить целостно: приложение, сервер, БД, сеть и внешние сервисы