В системах интеллектуальной обработки документов корректность извлечения данных — это лишь половина дела. Гораздо важнее, чтобы при скачке нагрузки сервис не превратился в бутылочное горлышко.

В этой статье расскажем, как мы:

  • автоматизировали нагрузочное тестирование, сократив ручную работу инженеров на 85%;

  • встроили стресс-тесты в CI/CD, чтобы каждая фича доказывала свою устойчивость перед релизом;

  • научились предсказывать поведение системы не на глаз, а по данным — даже при росте объемов в несколько раз.

Как автоматизировали тестирование

Раньше мы проводили нагрузочное тестирование вручную: тестовые окружения разворачивались распределенно, но настройка требовала значительных усилий, а метрики собирались с помощью встроенных средств Windows и Linux. По мере роста нагрузки и усложнения инфраструктуры (в том числе за счет поддержки различных ОС, таких как Windows, Astra Linux, Red OS) стало ясно, что такой подход не масштабируется.

Чтобы упростить процесс нагрузочного тестирования, мы попробовали написать простые скрипты на Python. Они частично автоматизировали запуск тестов, сбор логов и метрик. Это стало первым шагом к систематизации.

Сейчас мы перешли к полной автоматизации и тесты стали неотъемлемой частью CI/CD — они запускаются по расписанию, при изменениях в dev-ветке или вручную, а анализ результатов занимает считанные минуты.

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

  • Apache JMeter — для моделирования пользовательских сценариев с различным профилем нагрузки

  • Prometheus и Grafana — для сбора, хранения и визуализации метрик производительности. Prometheus собирает данные в реальном времени, а Grafana предоставляет наглядные дашборды для анализа показателей системы. для сбора и визуализации метрик производительности. Метрики агрегируем по медиане

  • Windows Performance Counter — для мониторинга системных ресурсов на платформе Windows, таких как использование CPU, памяти, диска и сети, что позволяет отслеживать внутренние показатели во время тестирования

  • Azure Pipeline — для автоматизации запуска тестов и публикации результатов, включая метрики и графики в Grafana

Какие тесты используем и когда

Частая ошибка — считать performance testing и load testing одним и тем же. На практике это разные этапы проверки системы:

  • Performance testing — измеряет скорость обработки документов в рабочих условиях

  • Load testing — ищет предельные возможности инфраструктуры

У нас еженедельные performance tests — это не просто замеры, а способ отследить влияние изменений конфигурации. Например, переход с метрики «документы» на «страницы» дал более точные данные, так как документ может быть и 5-страничным договором, и 300-страничным каталогом.

Load testing строится иначе. Методично увеличивая нагрузку (объем данных или число параллельных потоков), мы находим:

  • точку деградации производительности

  • предел пропускной способности

  • условия для критических сбоев

Особый интерес для нас представляют soak-тесты. Их отличие — в продолжительности (48+ часов вместо 4-8). За это время успевают проявиться утечки памяти, накопление временных файлов, а также постепенная фрагментация ресурсов. Такие проблемы обычно незаметны при стандартных проверках, но критичны для production-окружения.

Регулярные тесты позволяют быстро находить узкие места и дефекты. Например, при рефакторинге обработки очередей под Linux были актуализированы feature-теги. Перед мержем в dev-ветку мы провели нагрузочные тесты. Оказалось, что производительность не снизилась, но потребление памяти исполнителями станции обработки выросло более чем на 80% из-за нового объекта класса в коде.

Ниже представлены графики, на которых наглядно видна проблема.

ДО правок
ДО правок
ПОСЛЕ правок
ПОСЛЕ правок

Сценарии тестирования

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

  • типу входящих документов: маленькие (до 10 страниц), средние (до 80 страниц), большие: многостраничные (300+страниц) и тяжелые (30Мб+)

  • профилю нагрузки: обработка через Hot Folder или API, параллельная обработка

  • длительности тестов: от 4 до 8 часов (регулярные тесты), 48+ часов (soak-тесты)

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

Конфигурация тестового контура

Регулярные и релизные тесты мы проводим на отдельных фермах (инфраструктурах, состоящих из нескольких физических машин). При этом стараемся сделать ферму максимально приближенной к той распределенной конфигурации, которая есть у пользователей наших продуктов.

Для ОС Windows и Linux у нас есть две идентичные по характеристикам фермы (процессоры, количество ядер, RAM, диски и т.д.). Это позволяет сравнивать поведение кроссплатформенной части системы и выявлять ОС-специфичные аномалии.

Ключевые метрики тестирования

В ходе тестирования мы осуществляем комплексный мониторинг системы, собирая два типа метрик. Во-первых, отслеживаем потребление системных ресурсов. Во-вторых, параллельно анализируем такие показатели, как:

  • среднее время обработки одного пакета

  • общее количество обработанных пакетов за фиксированный интервал времени

  • потребление памяти процессами нашего комплекса

  • рост файлового хранилища

Такую метрику, как рост файлового хранилища начали отслеживать совсем недавно. Для работы комплекса требуется хранить большие объемы данных — проектные и временные файлы. Обычно для этого используются внешние хранилища: локальные папки, распределенные или облачные системы (например, S3). Такой подход обеспечивает гибкость и масштабируемость, но ведет к быстрому росту данных. Увеличение объема хранилища напрямую влияет на затраты и возможности масштабирования системы. Мониторинг этой метрики позволил точнее оценивать эффективность использования ресурсов, оптимизировать хранение данных и планировать развитие инфраструктуры.

Все метрики собираем через Prometheus, агрегируем по медиане и анализируем на дашбордах Grafana.

Пример работы алгоритма тестирования

У нас была задача сравнить производительности: dev-версии и нового релиза ContentCapture на сценарии маленьких пакетов по API. Один пакет включал в себя 4 документа, общий размер — 10 МБ. Продолжительность теста составляла 4 часа. Использовали базу данных PostgreSQL

В таблице ниже показали результаты нагрузочных тестов.

Вывод по результатам тестирования. Dev-сборка по производительности близка к релизу. Потребление памяти чуть выше, но в пределах допустимых 5%. Этот порог учитывает естественные колебания в работе железа и сети. Разница не влияет на работоспособность.

Визуализация результатов

По завершении нагрузочных тестов у нас автоматически формируются дашборды в Grafana. Это упрощает анализ результатов и отслеживание изменений во времени.

Вот так выглядел дашборд для задачи, описанной в предыдущем разделе статьи.

Планы

Процесс разработки нагрузочного тестирования у нас организован итеративно. Все необходимые доработки и улучшения фиксируем в бэклоге технического долга и планируем в рамках регулярных спринтов. Это позволяет постепенно повышать качество и эффективность тестирования, интегрируя новые возможности в повседневную практику.

 Вот что хотим внедрить в ближайшее время:

  • унифицировать установку тестового окружения с использованием Helm и Docker Compose

  • автоматизировать генерацию отчетов для сравнения производительности между релизами (интеграция с дашбордом Grafana)

  • настроить оповещения в Grafana для оперативного оповещения о снижении производительности по ключевым показателям производительности

Вместо заключения

Нагрузочное тестирование перестало быть рутиной и стало частью нашей культуры разработки. Оно экономит время, предотвращает ночные ЧП и, главное — дает уверенность, что система справится с реальной нагрузкой.

А как вы тестируете подобные системы, какие метрики считаете ключевыми, какие инструменты оказались бесполезны?

Комментарии (0)