# Нагрузочное тестирование

Нагрузочное тестирование используется для оценки поведения Global ERP под рабочей, пиковой и длительной нагрузкой. Основной инструмент генерации нагрузки — JMeter.

Нагрузочное тестирование может охватывать:

- серверы приложений Global ERP;
- PostgreSQL;
- файловое хранилище;
- REST API и внешние интерфейсы;
- фоновые задания и планировщики;
- пользовательские операции в HTML5-клиенте;
- операции загрузки, скачивания и обработки файлов.

Для каждого прогона фиксируются:

- цель теста;
- тестируемый контур;
- версия приложения;
- версия БД;
- состав инфраструктуры;
- объем тестовых данных;
- профиль нагрузки;
- параметры JMeter-сценария;
- время начала и окончания теста;
- ссылки на отчет JMeter, мониторинг и логи.

## Подготовка тестирования

### Готовность стенда

Перед запуском нагрузочного тестирования необходимо проверить готовность тестового стенда, мониторинга, PostgreSQL и сервера JMeter. Для этого используется чек-лист из раздела [Подготовка к нагрузочному тестированию](https://help.globalerp.ru/books/G3SysAdminDoc/SNAPSHOT/html/130_monitoring_system/070_load_testing_readiness.html).

Отдельно проверьте, что сервер JMeter не является ограничивающим фактором. Требования к генератору нагрузки описаны в разделе [Проверка сервера JMeter](https://help.globalerp.ru/books/G3SysAdminDoc/SNAPSHOT/html/130_monitoring_system/070_load_testing_readiness.html#jmeter).

### Инструмент нагрузочного тестирования

Для генерации нагрузки используется JMeter.

Через JMeter можно запускать:

- HTTP/API-сценарии;
- REST-вызовы;
- пользовательские сценарии.

### Тестовые данные

Тестовые данные должны соответствовать цели нагрузочного теста и ожидаемому объему промышленной эксплуатации.

В описании теста указываются:

- количество пользователей;
- количество ролей и профилей;
- объем справочников;
- количество документов и бизнес-объектов;
- объем файловых вложений;
- объем БД;
- наличие исторических данных;
- наличие данных для отчетов и печатных форм.

Если тест проверяет конкретный пользовательский сценарий, дополнительно указывается набор данных, который нужен для выполнения этого сценария: документы, контрагенты, договоры, настройки, файлы или другие объекты.

### Сценарии нагрузки

Сценарий нагрузки должен описывать конкретные операции, которые выполняет JMeter.

В сценарий могут входить:

- авторизация пользователя;
- открытие выборки;
- применение фильтра;
- открытие карточки объекта;
- создание и сохранение объекта;
- выполнение операции;
- формирование печатной формы;
- загрузка или скачивание файла;
- вызов REST API.

Пример пользовательского сценария:

1. Выполнить авторизацию.
2. Открыть выборку документов.
3. Применить фильтр.
4. Открыть карточку документа.
5. Изменить атрибут.
6. Сохранить документ.
7. Сформировать печатную форму.
8. Проверить HTTP-статус и время ответа.

### Профиль нагрузки

Профиль нагрузки определяет распределение запросов во времени.

В профиле указываются:

- количество виртуальных пользователей;
- длительность ramp-up;
- длительность основной фазы теста;
- частота выполнения операций;
- распределение операций между сценариями;
- допустимый процент ошибок;
- критерии остановки теста.

Пример профиля:

| Группа нагрузки | Операция | Количество пользователей / потоков |
|---|---|---|
| Пользователи | Открытие выборок | `указать значение` |
| Пользователи | Создание и сохранение документов | `указать значение` |
| Пользователи | Формирование отчетов | `указать значение` |
| API | REST-вызовы | `указать значение` |

### Мониторинг

Во время теста контролируются:

- состояние pod’ов серверов приложений;
- CPU и RAM;
- JVM heap;
- GC;
- активные сессии;
- состояние PostgreSQL;
- активные запросы и блокировки в БД;
- долгие SQL-запросы;
- HTTP-статусы ответов;
- состояние фоновых заданий;
- состояние файлового хранилища;
- состояние сервера JMeter.

Для анализа PostgreSQL можно использовать SQL-запросы из раздела [Основные SQL-запросы для анализа](https://help.globalerp.ru/books/G3SysAdminDoc/SNAPSHOT/html/130_monitoring_system/070_load_testing_readiness.html#sql).

## Создание и настройка

Настройка нагрузочного теста включает:

1. Подготовку тестового стенда.
2. Проверку готовности стенда по админской инструкции.
3. Подготовку тестовых данных.
4. Подготовку JMeter-сценария.
5. Настройку Thread Group.
6. Настройку HTTP-запросов или REST-вызовов.
7. Настройку авторизации.
8. Настройку профиля нагрузки.
9. Настройку Listener’ов.
10. Подготовку места хранения логов и отчета.

В JMeter-сценарии указываются:

- адрес тестового стенда;
- база данных или контур, если они передаются в заголовках или URL;
- учетные данные или токен тестового пользователя;
- путь REST API;
- тело запроса;
- количество потоков;
- ramp-up;
- длительность теста;
- таймауты;
- правила проверки HTTP-статусов;
- параметры сохранения результата.

## Запуск тестов

Нагрузочное тестирование выполняется в два этапа: сначала проводится пилотный запуск, затем основной прогон. Минимальный JMeter-сценарий используется как шаблон для настройки и проверки запуска.

### Пилотный запуск

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

При пилотном запуске проверьте:

- доступность тестового стенда;
- корректность URL и параметров JMeter;
- авторизацию;
- корректность тестовых данных;
- отсутствие ошибок в сценарии;
- сбор метрик и логов;
- состояние сервера JMeter.

Требования к проверке сервера JMeter описаны в разделе [Проверка сервера JMeter](https://help.globalerp.ru/books/G3SysAdminDoc/SNAPSHOT/html/130_monitoring_system/070_load_testing_readiness.html#jmeter).

Если пилотный запуск выявил ошибки, основной прогон не выполняется до их устранения.

### Основной запуск

Основной запуск выполняется после успешного пилотного прогона.

Перед запуском необходимо убедиться, что в JMeter-сценарии указаны:

- адрес тестового стенда;
- база данных или контур, если они передаются в URL или заголовках запроса;
- учетные данные или токен тестового пользователя;
- путь REST API или URL пользовательского сценария;
- тело запроса, если сценарий выполняет POST- или PUT-запросы;
- количество потоков в Thread Group;
- ramp-up и длительность теста;
- таймауты;
- правила проверки HTTP-статусов;
- Listener’ы для анализа результата.

Во время запуска фиксируются:

- время начала и окончания теста;
- версия приложения;
- параметры стенда;
- параметры JMeter;
- профиль нагрузки;
- количество виртуальных пользователей;
- длительность теста;
- ссылки на Grafana, Loki, Pyroscope и отчет JMeter.

После завершения теста проверьте результаты в `View Results Tree`, `Summary Report`, `Aggregate Report` или другом настроенном Listener’е.

### Минимальный JMeter-сценарий

Для первичной настройки можно использовать минимальный JMeter-сценарий нагрузочного тестирования.
[Пример минимального JMeter-сценария](/050_tools/files/loadTest_minimal.jmx)

```{note}
Если JMeter-сценарий использует WebSocket-соединения, необходимо установить плагин [JMeter WebSocket Samplers](https://bitbucket.org/pjtr/jmeter-websocket-samplers/src/master/).
```

Минимальный сценарий содержит:

- блок переменных `variables`;
- переменные `server_name`, `port`, `login`, `UserCount`;
- thread group `TestFirst`;
- открытие WebSocket-соединения;
- авторизацию пользователя;
- выполнение JEXL-запроса;
- проверку успешного ответа через `Response Assertion`;
- извлечение данных ответа через `JSON Extractor`;
- закрытие WebSocket-соединения;
- отчеты `View Results Tree`, `Summary Report` и `Aggregate Report`.

Перед запуском минимального сценария:

1. Укажите имя сервера в переменной `server_name`.
2. Укажите порт в переменной `port`.
3. Укажите пользователя, пароль и базу в переменной `login`.
4. Укажите количество потоков в переменной `UserCount`.
5. Проверьте JEXL-запрос в шаге выполнения сценария.
6. Проверьте условие успешного ответа в `Response Assertion`.
7. Запустите тестирование через операцию **Start** на панели инструментов.
8. Дождитесь завершения теста.
9. Проверьте результаты в `View Results Tree`, `Summary Report` или `Aggregate Report`.

Подробный отчет по запросам, времени ответа и ошибкам анализируется в Listener’ах JMeter и в сохраненном отчете запуска.

## Проверка результата

После завершения теста анализируются результаты JMeter, метрики Global ERP и состояние инфраструктуры.

**В отчете JMeter проверяются:**

- количество запросов;
- количество успешных и ошибочных запросов;
- среднее, минимальное и максимальное время ответа;
- медианное время ответа;
- 95-й и 99-й перцентили;
- throughput;
- error rate.

**По Global ERP и инфраструктуре дополнительно анализируются:**

- CPU и RAM pod’ов приложения;
- JVM heap и GC;
- активные сессии;
- HTTP-ошибки;
- ошибки приложения в логах;
- активные запросы PostgreSQL;
- долгие SQL-запросы;
- блокировки;
- количество соединений с БД;
- состояние фоновых заданий;
- файловое хранилище;
- состояние сервера JMeter.

**Критерии успешности задаются до запуска теста.** Например:

- 95-й перцентиль по основным операциям не превышает согласованное значение;
- процент ошибок не превышает согласованное значение;
- в логах приложения нет необработанных ошибок уровня `ERROR`;
- в БД нет критичных блокировок;
- сервер JMeter не является ограничивающим фактором;
- JVM heap стабилен после прогрева;
- фоновые задания завершились корректно.

**По итогам анализа необходимо определить:**

- выдержала ли система заданный профиль нагрузки;
- какие операции имеют наибольшее время ответа;
- какие SQL-запросы дают основную задержку;
- есть ли блокировки в БД;
- есть ли рост JVM heap;
- есть ли длительные GC-паузы;
- равномерно ли распределена нагрузка между pod’ами;
- не стал ли JMeter ограничивающим фактором;
- требуется ли масштабирование или оптимизация.

## Особенности нагрузочного тестирования

В зависимости от цели проверки используются разные виды нагрузочного тестирования:

- **Тестирование производительности** — выполняется при ожидаемой рабочей нагрузке и проверяет время отклика и процент ошибок в штатном профиле нагрузки.
- **Стресс-тестирование** — выполняется при нагрузке выше расчетной и помогает определить предел системы и условия деградации.
- **Тестирование устойчивости** — выполняется при длительной стабильной нагрузке и помогает выявить деградацию во времени, утечки памяти, рост времени отклика и блокировки.
- **Пиковое тестирование** — проверяет поведение системы при резком увеличении нагрузки: массовом входе пользователей, одновременном открытии выборки, запуске отчетов или всплеске REST-запросов.

При нагрузочном тестировании чаще всего выявляются следующие узкие места:

- долгие SQL-запросы;
- отсутствие или неэффективность индексов;
- блокировки в БД;
- нехватка соединений в пуле;
- нехватка CPU или RAM;
- частые или длительные GC-паузы;
- неравномерное распределение нагрузки между pod’ами;
- медленная работа файлового хранилища;
- избыточные фоновые задания;
- ограничения сервера JMeter.

По результатам теста могут выполняться:

- увеличение количества pod’ов серверов приложений;
- изменение CPU/RAM limits и requests;
- настройка JVM;
- оптимизация SQL-запросов;
- добавление или изменение индексов;
- настройка пула соединений с БД;
- настройка PostgreSQL;
- изменение частоты фоновых заданий;
- настройка балансировщика нагрузки.

## Изоляция и повторяемость

Для сравнения результатов каждый запуск должен выполняться при зафиксированных параметрах:

- версия приложения;
- параметры инфраструктуры;
- объем тестовых данных;
- профиль нагрузки;
- параметры JMeter;
- состав фоновых заданий.

Если тест изменяет данные или файловое хранилище, перед следующим запуском необходимо восстановить стенд.

Перед прогоном по согласованию с администратором БД можно сбросить накопительную статистику PostgreSQL, чтобы анализировать только интервал нагрузочного теста. SQL-запросы для проверки расширений, сброса статистики и анализа `pg_stat_statements` / `pgpro_stats` приведены в разделе [Основные SQL-запросы для анализа](https://help.globalerp.ru/books/G3SysAdminDoc/SNAPSHOT/html/130_monitoring_system/070_load_testing_readiness.html#sql).

## Интеграция в массовый запуск или CI/CD

В CI/CD можно запускать:

- короткий JMeter-тест на основные API после сборки;
- smoke-нагрузочный тест;
- ночной нагрузочный тест;
- тест перед релизом;
- сравнение результатов с предыдущей стабильной версией.

Результат CI/CD-запуска анализируется по пороговым значениям метрик. При превышении порогов команда должна получить уведомление.

## Типовые проблемы

При нагрузочном тестировании часто возникают следующие проблемы:

- тестовая среда отличается от промышленной;
- JMeter-сервер размещен на узлах приложения, БД или мониторинга;
- сервер JMeter упирается в CPU, RAM, сеть или диск;
- сценарии не отражают реальные действия пользователей;
- объем тестовых данных не соответствует промышленному;
- не настроен сбор метрик и логов;
- не зафиксирован профиль нагрузки;
- не определены критерии успешности;
- фоновые задания искажают результаты;
- одиночный запуск используется как основание для окончательных выводов.

## Рекомендации

Рекомендуется:

- использовать JMeter как единый инструмент генерации нагрузки;
- выполнять пилотный прогон перед основным тестом;
- фиксировать параметры каждого запуска;
- проверять, что JMeter не стал узким местом;
- хранить отчеты JMeter и ссылки на дашборды мониторинга;
- отдельно анализировать пользовательскую нагрузку и фоновые задачи;
- сравнивать результаты между версиями системы;
- выполнять повторное тестирование после оптимизации;
- проводить тестирование после крупных изменений в бизнес-логике, SQL-запросах, инфраструктуре или версии платформы.

## Ограничения

Нагрузочное тестирование не заменяет функциональные, интеграционные и UI-тесты.

При интерпретации результатов учитывайте:

- тестовая среда может отличаться от промышленной;
- результаты зависят от качества тестовых данных;
- фоновые задания могут влиять на результаты;
- одиночный запуск не является достаточным основанием для окончательных выводов.