
Если вы работаете с системами для управления корпоративным контентом, то понимаете, что главная их проблема — это недостаточный уровень производительности. То, что прекрасно работает на 20 документах, тормозит и выдает ошибки на 2 млн. Как узнать об этой проблеме до того, как система сдана клиенту в промышленную эксплуатацию? Ответ: провести нагрузочное тестирование.
Один из наших основных продуктов — платформа для управления корпоративным контентом LDM.CSP. Мы, архитекторы и инженеры команды LDM, регулярно, а не от случая к случаю, проводим нагрузочные тестирования и делаем подробные отчеты о результатах испытаний. В этой статье расскажем о методике проведения нагрузочного тестирования нашей платформы, опишем принципы и подходы, благодаря которым мы предоставляем нашим клиентам предсказуемые характеристики поведения системы для разных сценариев, а также упомянем подводные камни и практические аспекты, с которыми мы сталкивались в процессе.
Привет! Мы — Владимир Семенов, старший системный архитектор LDM (входит в холдинг LANSOFT), и Олеся Панкова, инженер по нагрузочному тестированию. В нашей статье — не сухие цифры из отчета, а экспертиза инженеров команды.
Хакатон или релизная процедура?
Часто нагрузочное тестирование проводят на внутренних хакатонах: вот вам стенд с имитацией 50 пользователей, проведите тестирование. Что в результате? Яркое событие для команды, можно узнать много полезного о системе, ну,и о самих себе. На открытых хакатонах можно проверить поведение системы при работе тысяч “живых” пользователей — это тоже важные данные, которые тяжело воспроизвести другим способом. Однако проверка производительности на таких мероприятиях все же не совсем подходит для планомерной работы по улучшению показателей платформы, хакатоны неудобно делать регулярно для каждого релиза системы (в нашем случае — два раза в год). Следовательно, это не рабочий процесс, а скорее тимбилдинг.
Мы решили пойти другим путем и сделать акцент на регулярные плановые работы, цель которых выявить слабые места платформы, повысить ее производительность и качество функционала. Разница между хакатонами и методической работой примерно такая же, как между тренировками под руководством наставника и игрой с друзьями в выходной.
Как устроен этот процесс? Есть базовый набор сценариев: создание и чтение документов, загрузка и скачивание файлов, атрибутивный и полнотекстовый поиск, к которому каждый релиз добавляются новые сценарии под новые функции. Если остается время — добавляются специальные проверки: 1) как зависит нагрузка от размера файла; 2) меняем те или иные характеристики у сервисов и смотрим, как меняются нагрузочные характеристики, как себя ведет вся система.
Подготовка к испытаниям: инструменты, сценарии, инфраструктура
Тестирование проводится на выделенном стенде, развернутом в соответствии с рекомендованной архитектурой LDM.CSP. Система функционирует на базе микросервисной архитектуры под управлением оркестратора контейнеров Kubernetes.
Моделирование нагрузки производится с использованием инструментов нагрузочного тестирования путем эмуляции действий определенного количества пользователей. В процессе тестирования каждый виртуальный пользователь (программный процесс, эмулирующий действия физического пользователя) циклически производит выполнение пользовательского сценария.
Инструменты:
Основной механизм подачи нагрузки — Gatling. Почему мы выбрали его:
-
Скрипты пишутся кодом — удобнее для инженеров, которые привыкли к IDE и Git.
-
Gatling позволяет подавать очень высокие нагрузки (до 5000+ RPS без проблем).
-
JMeter сложнее в настройке для больших нагрузок, LoadRunner бесплатен только до 50 пользователей.
Важный нюанс: выбор инструмента для подачи нагрузки — это во многом вопрос привычки команды, однако Gatling обладает преимуществами перед другими популярными инструментами.
Инфраструктура:
-
Стенд — Kubernetes, 24 узла, 142 vCPU, 64 GB RAM.
-
Генератор нагрузки: 32 ядра, 64 GB RAM.
-
Тестирование начинается с одного инстанса, затем добавляются узлы, проверяется линейность масштабирования.
-
Цель — подтвердить работу с несколькими миллионами документов в день на разумном «железе».
-
Фактура — предварительно загруженная база данных: примерный объем документов, которые используются (объем заполнения предварительно описан в методике).
-
В стандартном режиме используется 5000 политик доступа.
Сценарии:
Нагрузка моделируется через виртуальных пользователей, каждый из которых циклически выполняет заданный сценарий. Нагрузочные испытания проводят на базовом профиле с уже заданным списком сценариев, которые входят в нагрузку. Тестирование проходит для каждого сценария по отдельности:
-
Создание документа (Create Document)
-
Загрузка файла (Upload File)
-
Чтение документа (GetById)
-
Чтение документов (GetAll)
-
Получение метаданных файла (GetFileInfo)
-
Скачивание файла (GetFile)
Зачем это делается по отдельности? Разные заказчики используют платформу по-разному: кому-то более важны операции загрузки документов, кому-то — операции поиска.
Если клиенту нужен смешанный профиль — пишем кастомный сценарий, в котором будет учитываться общая производительность по нескольким видам операций сразу.
Моделирование нагрузки:
Для удобства тестирование проводится в несколько этапов. На первом этапе мы определяем и подтверждаем максимальную производительность 1 инстанса каждого из сценариев, входящих в профиль. Далее мы определяем максимальную производительность 1-2-4-6-8 инстансов каждого из микросервисов. На финальном этапе мы оцениваем способность системы сохранять заданный уровень производительности и доступности при длительном воздействии нагрузок каждого из микросервисов, входящих в профиль.
Продолжительность:
Серия испытаний занимает около месяца. Испытания идут поэтапно: протестировали, получили результаты по первому сценарию, идем дальше. Если обнаруживаем какие-то проблемы, которые могут быть связаны с настройками, со стендами, перепроверяем. Опять получаем результаты, и только если проблем больше нет, переходим к следующему этапу.
Как проверяем ошибки:
Первый этап проверки ошибок — возврат метода. Либо метод выдает ошибку напрямую, либо демонстрирует успешный результат, когда на самом деле проблема произошла, такой результат вручную записываем как баг. Кроме прямых ошибок при запуске теста по методам смотрим поведение системы. Метрики снимаются на протяжении всего времени подачи нагрузок, есть стандарты по метрикам, т.е. в течение всего времени не должно быть превышений по определенным показателям.
Следующий этап — косвенная проверка. В этом случае может проверяться согласованность операций, появление новых данных или их статус в базе данных. Например, при загрузке файла тест прошел успешно, а при скачивании того же файла выдается ошибка. Т.е. файл на самом деле не загрузился или загрузился с ошибкой.
Отчет:
Формирование отчета с результатами — это отдельный вид работ, он автоматизирован и готовится поэтапно после каждой серии испытаний. В финале тестирования мы получаем не только чувство глубокого удовлетворения, но и полностью готовый к публикации отчет. Поэтому после проведения нагрузочного тестирования публикуем результаты испытаний по разным видам операций соответственно.
Результаты
Теперь самое интересное, делимся результатами с фрагментами отчета. Здесь заодно можно увидеть, в каком виде мы формируем отчет.
Результаты производительности работы одного узла.

Даже при использовании одного узла система демонстрирует высокую производительность и эффективное потребление ресурсов. Все тесты подтверждения максимальной производительности прошли успешно, а ключевые показатели производительности находились в рамках SLA.
Сравнение результатов нагрузочного тестирования релизов платформы LDM.CSP 1.9 и 1.11

По сравнению с нагрузочным тестированием версии 1.9 платформа LDM.CSP 1.11 продемонстрировала заметный рост производительности по всем ранее протестированным сценариям. Наибольший прирост был достигнут в операциях создания документов (+133%) и получения документа по идентификатору (+100%).
В версии 1.11 были реализованы оптимизации, сформированные по итогам нагрузочного тестирования версии 1.9, а также выполнено обновление используемых компонентов и библиотек до более современных версий. Как результат, мы получили более эффективные обработку запросов и использование вычислительных ресурсов.
На этом работа не заканчивается. Результаты тестирования 1.11 уже легли в основу следующего этапа оптимизации платформы. Часть выявленных направлений будет реализована в версиях 1.12 и 1.13, после чего мы повторим нагрузочные испытания и сравним результаты. Именно так постепенно улучшается производительность платформы — от релиза к релизу, на основе объективных данных, а не предположений.
Результаты производительности платформы LDM.CSP 1.11 в диапазоне от 1 до 8 инстансов и испытания масштабируемости.

По результатам проведенных испытаний платформа продемонстрировала эталонную линейную масштабируемость в рабочем диапазоне по всем сценариям.
Узкое место — база данных

Однако в сценарии получения списка документов было обнаружено узкое место по масштабируемости поисковых запросов, опирающихся на ресурс базы данных.
Мгновенный расчет политик доступа (ABAC, RBAC, ACL — 5000 политик всего): даже при наличии такого большого количества политик доступа наша платформа показывает результат обработки нескольких миллионов документов в день — это соответствует требованиям наших заказчиков, для которых управление доступом является одним из критичных факторов при использовании системы.
Проблемы и узкие места
Поскольку мы решили показать нашу кухню, то открываем все шкафчики. И показываем не только успешные результаты, но и выявленные в ходе тестирования проблемы и узкие места.
Узкое место — база данных
Основное узкое место было связано со сценарием получения списка документов. В чем было дело? В этом сценарии система обращается к базе данных при обработке поискового запроса. Нагрузка на сервис происходит эффективно без ошибок, но нагрузка на базу данных приводит к росту насыщения и очередей. Причина в том, что сами по себе поисковые запросы к базе данных являются тяжелыми. Т.е. проблема не в самой платформе, а в базе данных — и решается на стороне заказчика.
Поскольку мы не всегда контролируем, что делает пользователь, то в таком случае мы даём референсные значения, а заказчик уже сам решает: упрощать ли запросы, брать более мощную БД или менять архитектуру решения добавляя витрины данных.
Интересный сценарий
Это была скорее не проблема, а интересный сценарий, о котором тоже хотим рассказать. Мы неожиданно столкнулись с ограничением сетевой карты при подаче нагрузки на загрузку файла.
Во время тестирования нагрузка подавалась через одну гигабитную карту. То есть виртуальных машин было несколько, а вот карта у физического сервера была одна. В результате при достижении высоких показателей RPS (200-300) масштабирование перестало быть линейным из-за ограничения пропускной способности этой сетевой карты.
Для обхода данного ограничения генератор нагрузки был подключен к той же сети, что и worker-нода, где размещен файловый сервис.
Не сразу выяснили, в чем проблема, потому что нечасто упираемся в сетевые эффекты.
Проблема — фрагментация памяти
При проведении предыдущего нагрузочного тестирования столкнулись с большой фрагментацией памяти. Не могли понять, в чем дело. В итоге для Java-сервисов меняли аллокатор памяти, который стандартно входил в поставку. Поставили другой, который был устойчив к многопоточному выделению памяти. После этого удалось обеспечить короткие транзакции.
Зачем вообще нужны нагрузочные тестирования?
Вообще, для команды инженеров это дополнительная нагрузка. Не секрет, что регулярное нагрузочное тестирование — дорогое удовольствие для компании. Но его главный козырь — предсказуемость поведения системы при различных сценариях.
В открытых источниках редко встречаются полные отчеты по нагрузке — чаще можно встретить одну общую цифру. Как ее получили — неизвестно. Можно ли ей доверять — непонятно. Мы предоставляем заказчикам референсные значения, проверенные тестами, для того, чтобы заказчики могли примерять результаты нашей системы на свои процессы и целевые показатели.
Что дальше: планы на будущие тесты
От релиза к релизу мы будем увеличивать объем тестов, которые мы проводим.
Ближайшие планы по нагрузочным тестированиям:
-
Протестировать не только синтетические сценарии, но и реальные запросы от приложений, построенных на LDM.CSP.
-
Расширять базу сервисов, охваченных нагрузочным тестированием.
Сегодня мы рассказали вам о результатах нагрузочного тестирования 4 сценариев работы. В следующих статьях расскажем о результатах работы других сценариев.
ссылка на оригинал статьи https://habr.com/ru/articles/1061680/