Комплексная трёхуровневая система тестирования производительности для микросервисной архитектуры на JVM-стеке.
| Библиотека | Версия | Назначение |
|---|---|---|
| Spring Boot | 3.4.3 | Основной фреймворк |
| Kotlin | 2.1.0 | Язык реализации |
| Spring MVC | (BOM) | REST API |
| Spring Data JPA | (BOM) | ORM-слой |
| Spring Data Redis (Lettuce) | (BOM) | Distributed-кэш |
| Spring Actuator | (BOM) | Health, метрики |
| Spring WebFlux | (BOM) | WebClient (транзитивная зависимость) |
| Jackson + Kotlin Module | (BOM) | JSON-сериализация |
| kotlinx.serialization | 1.6.3 | JSON-сериализация (альтернатива) |
| Gson | 2.10.1 | JSON-сериализация (альтернатива) |
| OkHttpClient | 4.12.0 | HTTP-клиент |
| Caffeine | 3.1.8 | In-process LRU-кэш |
| HikariCP | (BOM) | Пул соединений PostgreSQL |
| Flyway | (BOM) | Версионирование схемы БД |
| PostgreSQL JDBC | (BOM) | Драйвер БД |
| Resilience4j | 2.2.0 | Circuit Breaker |
| Chaos Monkey for Spring Boot | 3.1.0 | Инъекция сбоев |
| Micrometer + Prometheus | (BOM) | Экспорт метрик |
| Библиотека | Версия | Назначение |
|---|---|---|
| JMH | 1.37 | Микробенчмарки |
| Gatling | 3.11.3 | Нагрузочное тестирование |
| Toxiproxy Java Client | 2.1.11 | Управление сетевым хаосом из тестов |
| OkHttpClient + MockWebServer | 4.12.0 | HTTP-клиент и мок-сервер в JMH |
| JUnit 5 | (BOM) | Фреймворк для хаос-тестов |
| Сервис | Образ | Порт |
|---|---|---|
| PostgreSQL | postgres:15-alpine | 5432 |
| Redis | redis:7-alpine | 6379 |
| Toxiproxy | ghcr.io/shopify/toxiproxy:2.9.0 | 8474, 15432, 16379 |
| InfluxDB | influxdb:2.7-alpine | 8086 |
| Prometheus | prom/prometheus:latest | 9090 |
| Grafana | grafana/grafana:10.2.3 | 3000 |
Система организована как мультимодульный проект. Основные компоненты:
- target-app — целевое Spring Boot приложение (мишень).
- performance-tests — тесты производительности (бенчмарки, нагрузка, хаос).
- reports — агрегированные отчеты о тестировании.
Подробная структура папок и файлов описана в разделе Структура проекта в архитектурной документации.
- JVM 21+ (рекомендуется 21, поддерживается до 25 включительно)
- Docker & Docker Compose
cd performance-tests/infradocker-compose up -d| Сервис | Порт | Описание |
|---|---|---|
| PostgreSQL | 5432 | База данных |
| Redis | 6379 | Распределённый кэш |
| Toxiproxy | 8474 | Сетевой хаос |
| InfluxDB | 8086 | Хранение метрик Gatling |
| Telegraf | 2003 | Приём Graphite-метрик Gatling и запись в InfluxDB |
| Prometheus | 9090 | Сбор метрик Actuator |
| Grafana | 3000 | Дашборды (admin / admin) |
Чтобы посмотреть метрики Gatling в Grafana, поднимите инфраструктуру и затем запустите нагрузочный тест:
cd performance-tests/infra
docker-compose up -d./gradlew :performance-tests:load-tests:runLoadTest -Dprofile=smokeGatling пишет в Graphite-поток на localhost:2003, а Telegraf принимает его и складывает метрики в InfluxDB 2.x.
После прогона откройте Grafana на http://localhost:3000 и проверьте дашборды по Gatling/InfluxDB.
./gradlew :performance-tests:benchmarks:runBenchmarks| Бенчмарк | Режим | Что измеряется |
|---|---|---|
SerializationBenchmark |
Throughput | Jackson vs Gson vs kotlinx.serialization |
CacheBenchmark |
AverageTime | Caffeine: Cache Hit vs Cache Miss |
HttpClientBenchmark |
Throughput | OkHttpClient через MockWebServer |
BusinessLogicBenchmark |
Throughput | BenchmarkService.computeHeavyTask, сортировка и бинарный поиск |
Результаты сохраняются в reports/jmh_results.json. При первом запуске создаётся reports/jmh_baseline.json как эталон — при последующих локальных запусках деградация >10% блокирует сборку. В GitHub Actions baseline создаётся отдельным прогоном на том же runner, затем второй прогон сравнивается с ним с тем же порогом 10%.
Задача runLoadTest сама поднимает target-app (через bootJar) перед прогоном и останавливает его после — вручную запускать приложение не нужно:
# Smoke — 5 пользователей, быстрая проверка (по умолчанию)
./gradlew :performance-tests:load-tests:runLoadTest -Dprofile=smoke# Load — рабочая нагрузка 100→500 RPS, 10 минут
./gradlew :performance-tests:load-tests:runLoadTest -Dprofile=load# Stress — поиск предела: ramp до 2000 RPS за 5 минут
./gradlew :performance-tests:load-tests:runLoadTest -Dprofile=stress# Soak — долгосрочная стабильность: 200 RPS, 60 минут
./gradlew :performance-tests:load-tests:runLoadTest -Dprofile=soak# Spike — пиковая нагрузка: 10→1000→10 RPS
./gradlew :performance-tests:load-tests:runLoadTest -Dprofile=spike| Профиль | Нагрузка | p50 | p95 | p99 | Error rate |
|---|---|---|---|---|---|
smoke |
5 VU | <1000ms | <2000ms | <3000ms | <0.1% |
load |
100→500 RPS | <100ms | <300ms | <800ms | <0.1% |
stress |
→2000 RPS | <100ms | <300ms | <800ms | <0.1% |
soak |
200 RPS × 60min | <100ms | <300ms | <800ms | <0.1% |
spike |
10→1000→10 RPS | <100ms | <300ms | <800ms | <0.1% |
Отчёты сохраняются в reports/gatling/.
Если всё же нужно запустить
target-appвручную (например, для просмотра логов в отдельном окне) — не запускайте после этогоrunLoadTestнапрямую: задачаstartTargetAppподнимет второй процесс и упадёт из-за занятого порта 8080. Сначала погасите ручной процесс.
Убедитесь, что инфраструктура и target-app запущены, затем:
./gradlew :performance-tests:chaos-tests:test| Сценарий | Инструмент | Что проверяется |
|---|---|---|
| DB Chaos | Toxiproxy latency | Circuit Breaker на задержках БД |
| Cache Chaos | Toxiproxy bandwidth=0 | Fallback при недоступности Redis |
| Downstream Chaos | Chaos Monkey latency | Устойчивость при HTTP-задержках |
| Memory Pressure | Chaos Monkey memory | Поведение GC при атаке на Heap |
| Pod Kill | Actuator shutdown | Graceful shutdown |
💡 Совет: По умолчанию
target-appподключается к Postgres и Redis напрямую (localhost:5432,localhost:6379). В системе предусмотрен профильchaos, который перенаправляет трафик через прокси-порты Toxiproxy (15432,16379). Хаос-тесты автоматически используют этот профиль. Если вы хотите вручную проверить влияние сетевого хаоса на запущенное приложение, запускайте его с профилемchaos:./gradlew :target-app:bootRun --args='--spring.profiles.active=chaos'
То, что задокументировано/настроено, но пока не доведено до полностью рабочего состояния:
| Что заявлено | Текущее состояние | Что нужно сделать |
|---|---|---|
Сервис target-app поднимается в Docker Compose |
Сервис закомментирован в docker-compose.yml; Prometheus всё равно скрейпит target-app:8080 |
Либо раскомментировать сервис, либо убрать неактуальный scrape-таргет из prometheus.yml |
Система построена на принципах изоляции слоев и воспроизводимости тестов. Основные решения:
- Трехуровневая модель: разделение на микробенчмарки (JMH), нагрузочные (Gatling) и хаос-тесты (Toxiproxy).
- Автоматизация порогов: сборка блокируется при деградации производительности в JMH.
- Инфраструктура как код: полное окружение (Prometheus, Grafana, БД) разворачивается через Docker Compose.
- Отказоустойчивость: интеграция Resilience4j для проверки корректности работы Circuit Breaker в условиях сбоев.
Подробное описание библиотек и устройства модулей: ARCHITECTURE.md