Почему тестирование производительности важно
Функциональная корректность недостаточна. Приложение, работающее для одного пользователя, но падающее при 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)
Определяет максимальное количество пользователей/транзакций при соблюдении критериев.
Типы на диаграмме
Ожидаемые пользователи
Нормальные условия] 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 или оптимизация
Процесс
- Определить требования — Цели (отклик < 2с, throughput > 500 TPS)
- Определить сценарии — Какие действия симулировать
- Подготовить окружение — Подобие продакшена по железу и данным
- Создать скрипты — Автоматизировать (k6, JMeter, Gatling, Locust)
- Выполнить — Прогрессивная нагрузка: 10%, 25%, 50%, 75%, 100%
- Мониторить — Метрики приложения, сервера, БД, сети
- Анализировать — Сравнить с требованиями, найти узкие места
- Отчитаться и оптимизировать — Рекомендации, повторное тестирование
Упражнение: Определите сценарии тестирования производительности
Вы 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 |
|---|---|---|---|
| k6 | JavaScript | Современное API и нагрузочное | Да |
| JMeter | Java/GUI | Протокольное, enterprise | Да |
| Gatling | Scala | Высокопроизводительная симуляция | Да |
| Locust | Python | Распределённое, code-first | Да |
| Artillery | JavaScript | Быстрое API-тестирование | Да (core) |
Профессиональные советы
Совет 1: Тестируйте в окружении, подобном продакшену. Результаты с ноутбука разработчика бессмысленны. Используйте сопоставимое железо, объёмы данных и сетевую конфигурацию.
Совет 2: Мониторьте всё. Не только метрики приложения. CPU/память серверов, запросы БД, сетевая задержка, попадания в кэш CDN, время отклика внешних сервисов.
Совет 3: Установите baseline перед оптимизацией. Запустите тесты производительности до внесения изменений. Без baseline невозможно измерить, улучшила ли оптимизация что-либо.
Ключевые выводы
- Семь типов: нагрузочное, стрессовое, на выносливость, spike, объёмное, масштабируемость, ёмкость
- Каждый тип отвечает на свой вопрос о поведении под нагрузкой
- Ключевые метрики: время отклика (особенно P95/P99), пропускная способность, частота ошибок, утилизация ресурсов
- Требует окружения, подобного продакшену, и реалистичных данных
- Тестировать перед крупными релизами, ожидаемыми пиками и изменениями архитектуры
- Мониторить целостно: приложение, сервер, БД, сеть и внешние сервисы