Первые шаги в нагрузке

Всем привет! Меня зовут Александр Наумов, я работаю в IT больше 12 лет, из которых последние несколько лет занимаюсь тестированием. В SM Lab я курирую тестирование в продуктовых командах. Вообще, я адепт продуктового подхода — люблю, когда команды деплоят ценности продукта в продакшн, а не просто делают задачи.

efcd6b53aec384da94f2263bb875d38b.png

Расскажу вам небольшую историю из своей жизни. 

В SM Lab мы сделали MVP-проект, интернет-журнал о спорте. Собственно, о чём ещё может быть интернет-журнал от Спортмастера, да? Цель проекта — рассказать о спорте и в статье показать тематические товары. Соблазнить их заниматься спортом и переправить трафик в интернет-магазин для совершения покупки.

Собственно, мы так и сделали. Мы пришли к бизнесу, сказали, смотрите — MVP-проект мы выпустили! Все шикарно, трафик льется, как река, и уходит на продающий сайт. На что бизнес нам ответил — отлично, готовьте рассылку на 40 тысяч клиентов. Моя реакция немного сменилась — «О боже, мы не готовы! Мы не сдали проект в эксплуатацию!». 

Немножко кухни из SM Lab. 

Когда вы делаете MVP-проект, вы начинаете готовить документацию для передачи его в эксплуатацию. А ребята из эксплуатации как раз следят за трафиком, нагрузкой, серверами. Команда разработки, соответственно, идет делать дальше продуктовые таски и не занимается нагрузкой, не следит за серверами. Так что, если вы не сдались в эксплуатацию, метрик по серверам у нас нет. Появляются следующие вопросы:  

  • Какая нагрузка на данный момент?  

  • Сколько клиентов у нас сейчас на нашем проекте?  

  • Какой инструмент для нагрузки надо выбрать? (Потому что нагрузкой не занимался раньше никогда.) 

  • И вообще что делать?  

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

Первый — какой выбрать инструмент? Потому что нагрузку надо сделать сейчас, у нас промоакция пройдет через 3 недели. Искать нового человека в команду — это долго. В эксплуатацию сдаться мы не успеем. Значит, это будет делать команда. То есть один из первых вопросов — это какой вообще инструмент у нас должен быть. 

Второй — как писать сценарий для нагрузочного тестирования. 

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

Давайте по порядку, для наглядности приведу в посте скрины с выступления на HeisenBug, где я касался этой темы.

Как выбрать инструмент

6b1aeb9260e4b20210e5540069a59fcb.png

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

Обзор инструментов

Первый инструмент, который я начал смотреть, это инструмент K6. Какие его плюсы?  

  • Открытый исходный код.

  • Решение можно масштабировать.

  • Много метрик для анализа проблемы. 

Минусы

  • Нужно владеть языком программирования для написания сценарных тестов,

  • Трудночитаемый отчет. 

  • Можно напороться на лицензию. Когда у вас сжатые сроки, соответственно, это работает как триггер.

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

Следующий инструмент — это Gatling. Один из самых популярных. 

Плюсы:

  • Распространенный инструмент.

  • Высокая производительность.

  • Предоставляет прекрасные отчеты. 

  • Наглядный. 

  • Самое прекрасное — команда эксплуатации его использует, а значит, экспертиза в компании есть.

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

  • Нужно уметь запускать проект. 

  • Очень требовательный к памяти. Но это инструмент нагрузки, соответственно, он таким и должен быть. 

  • Инструмент ориентирован на опытного разработчика. А из команды эксплуатации, соответственно, нам никого не выделят. Поэтому это не наш вариант. 

  • У него сложная документация. 

Еще один инструмент — LoadRunner

Плюсы:  

  • Он был популярным. 

  • У него была высокая производительност. 

  • Богатый набор инструментов из коробки. 

  • GUI для создания скрипта. Это то, что меня прельстило. Дальше расскажу, почему. 

Ну, какие минусы. 

  • На тот момент, когда я выбирал инструменты, он требовал лицензию. А значит, априори не подходил мне, потому что у меня нет бюджетов, потому что это MVP-проект. 

Еще один популярный инструмент — Yandex.Tank

Плюсы:

  • Высокая производительность. 

  • Возможность создавать собственные модули. 

  • Есть онлайн-монитор нагрузки. 

  • Он общедоступный на старте, но это все-таки лучше, чем не иметь ничего. 

Минусы:  

  • Нет GUI для создания тестов.

  • Больше используется не для написания тестов, а для генерации нагрузки. То есть мне нужно где-то написать тесты, стравить эту Tank, тогда у меня получится нагрузка. 

  • Чтобы писать сценарные тесты, лучше владеть языком программирования. Пишутся они сложно.

Ну и следующий популярный инструмент — это JMeter

Плюсы

  • У него есть GUI. Это прекрасно. 

  • Хорошо описанный инструмент. 

  • Он популярный.

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

Минусы. 

  • Есть пределы по использованию памяти. Все, кто работал с JMeter, прекрасно знают, что он упирается в память. Надо оптимизировать. 

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

Какие были компетенции в команде

Когда я выбирал инструмент, то думал, что мы, скорее всего, выберем К6. Модно, молодежно. 

Потом посмотрел, кто у меня есть в команде. 

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

Какие есть навыки у ручных тестеров? Это, естественно, Postman, SQL, DevTools, Charles. Ручных тестировщиков у меня два, а автоматизатор один. Значит, выбор тут будет падать на ручное тестирование, потому что одного человека можно вытащить. Тем более, он очень хорошо разбирается в Postman и прекрасно знает проект. То есть, можно чуть-чуть пожертвовать ручным тестированием, не потерять в регрессии и начать писать нагрузку. 

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

И требования получились следующие. 

  • Нужен инструмент с GUI, потому что ручной тестировщик не будет писать код. 

  • Нужен анализ прохождения тестов. 

  • Он должен быть с низким порогом входимости, то есть должна быть подробная документация, широкое комьюнити. 

  • Он должен быть бесплатным, потому что, еще раз повторюсь, бюджета у меня нет. 

Соответственно, мы выбрали JMeter. А я для себя сделал вывод — прежде чем прыгать в данный колодец в поисках инструмента, надо поговорить с командой, кто вообще готов этим заниматься, а не ходить к ручному тестеру и просить: «Пожалуйста, Петя. давай ты начнешь заниматься нагрузкой, мы же ляжем потом». 

Надо было найти человека, посмотреть на его компетенции и идти искать инструменты. 

Как составить сценарий

Что ж, инструмент мы выбрали. Поняли, это будет JMeter. Но какой же будет сценарий?  

Выбор сценария

Во-первых, пошли немного в теорию. Какие виды проверок в нагрузке есть:  

  • проверка нагрузки системы,  

  • проверка стабильности системы,  

  • проверка отказоустойчивости,  

  • стресс-тестирование (когда мы резко и внезапно даем нагрузку на систему и смотрим, как она себя поведет),

  • какой объем система может переварить (отправить в базу данных, например),  

  • проверка возможностей системы (где у нее точка деградации, сколько она может съесть),  

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

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

Как же мы начали составлять сценарий. 

Одно из простых решений — мы пошли к разработчику и попросили: «Дорогой бэкэндер, скажи, какие популярные запросы?». Вот мы получили. 

9f7842d81a0b07e3af6eacb50eada779.png

Естественно, из этого ничего не понятно. Сценарий тут не составишь. Это 30 совершенно рандомных популярных запросов. Кажется, что это каша. Получили топ API-методов, но не знаем, что с этим делать? С этим особо ничего не сделаешь. 

Что ж, пойдем с другой стороны. Мы пошли к бизнесу и попросили рассказать, какие для него приоритетные фичи в нашем проекте. Что ответил бизнес? Это очень просто. Самое главное — чтобы работали статьи, на которые будем вести трафик. Чтобы фичи по созданию маршрутов для бега на той или иной локации тоже работали, чтобы статьи по тегам работали. То есть это некий каталог, где лежит куча статей. Можно зайти и выбрать нужный подраздел и читать. Также важно, чтобы люди могли составить себе информацию по питанию, режим дня и питания, онлайн-тренировки, которые на нашем ресурсе также приветствуются. 

Все замечательно. 

Пошли к продукту и к продукт-аналитикам. Начали спрашивать: «Ребята, вот у нас есть куча запросов, у нас есть куча фичей. Расскажите про такую штуку, а как вообще клиент ходит?». 

Нам выдали такую историю.

ee5d1d0269445aceb870c7cbdca58b7e.png

По ней видно, это CJM — карта пользователей клиента, как у клиенты ходят по продукту. Мы увидели, что на самом деле большинство клиентов заходят сразу в статью, возможно, уходят дальше на определенный тег, проваливаются в каталог, переходят в следующую статью, и, соответственно, уходят уже в интернет-магазин, либо покидают ресурс. По сути, это выход из нашей системы. 

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

Скрестив API-запросы и CJM, мы получили удобоваримый сценарий для нагрузочного тестирования. 

Что с нагрузкой

Для ответа на этот вопрос мы опять пошли к аналитикам, запросили у них данные и получили следующее — количество клиентов в неделю составляет около 400 тысяч, соответственно, среднее в день — 57 300 в день. 

Отлично, подумали мы. Теперь у нас есть некие данные, нужно собрать и посчитать, какую нагрузку мы на данный момент везем. Потому что, повторюсь, у нас нет доступа к мониторингам по серверам и мы не знаем, сколько у нас RPS. По итогам расчетов мы получили следующее. 

  • Средний трафик дневной — 57 тысяч пользователей

  • Количество подов на бэкэндах и фронтэндах по 7 штук. 

  • Тайм-реквест составляет около 120 миллисекунд. Следовательно, если посчитать, это около 8,3 RPS. 

Посчитали трафик в минуту. Поделили общий трафик на количество под, поделили на количество минут в дне, это около 1440, и получили, что на один под приходится где-то 5 человек в минуту. На все 7 подов это 40 человек в минуту. 2400 RPM — общая нагрузка на один под. 

Когда мы будем проводить тестирование 

Магазины Спортмастера разбросаны по всей России, мы присутствем во всех регионах. Трафик у нас льется фактически ежеминутно. Да, у нас нет окна. Да, у нас есть региональные особенности. Но окно нужно выбрать. Нужно выбрать его так, чтобы пострадало меньше всего пользователей. Отсюда сделали вывод —, а давайте посмотрим трафик, с каких регионов его идет больше всего. 

Для себя мы выделили Центральный, Южный, Уральский и Сибирский регионы. А тут картина уже совершенно другая. Это не 24 часа, а в два раза меньше. То есть если разница между Москвой и Петропавловском — это 10 часов, то разница между Москвой и Читой — это +5. А значит, посчитали неверно. Нам надо пересчитывать. 

Что ж, получаем новые данные. Добавляем активное время пользователя — 12 часов. То есть не 24, а только 12 часов пользователь более-менее активный, и именно этот трафик у нас является целевым. Ну, соответственно, давайте его и считать. Делим теперь уже на 720 минут и получаем, что на один под на самом деле приходится уже не 5, а 11 человек в минуту, на 7 — 80. А RPS у нас теперь стало почти 5500. У нас нагрузка увеличилась. Значит, нужно писать сценарий. 

Сценарий, к которому мы пришли

Во-первых, мы будем проводить только 4 сценария, а не 5, как попросил бизнес. Мы будем смотреть статью, проходить каталог статей, запрашивать определенные фичи по питанию, ходить по CJM с тренировками. 

Необходимо выбрать время. Мы выбрали период с 0:50 часов до 01:30. Этот период учитывает задачи и региональные особенности, описанные выше.

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

Результаты

Мы решили сразу взять и убить наш под. Соответственно, мы запустили нагрузку на 100 потоков. После проведения нагрузки через день мы получаем вот такой график. 

1f1eef31c8318a34a20749ef865742b9.png

Тут видно, что образование пиков соответствует той нагрузке, когда мы начинали ее повышать. И нас больше всего интересует точка, которая показывает, что у нас случилось в 00:55.

Вот график из Gatling.

2a8bc698e11d712d377132366abc9947.png

Здесь мы видим то, что уже где-то на 72 потоках (в пике было 170 RPS) идет точка деградации. То есть начинает уже долго отдавать методы, долго грузится страница. В принципе, мы тут уже начинаем сыпаться. Соответственно, это коррелируется с выводом на пике времени запроса. То есть у нас точка деградации — это 70. 

Выводы по такому обстрелу. 

  • 99-й перцентиль у нас около 60 тысяч миллисекунд,  

  • 95-й перцентиль — около 21 тысяч миллисекунд.

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

Мы решили дальше проверять систему на стабильность и начали потихонечку уменьшать количество потоков, чтобы понять, какое количество потоков вообще на данный момент мы готовы переварить. Получилось около 20 потоков. Соответственно, мы не уходили в потолок по памяти. Да, увеличение CPU было, но не в потолок.

Были пики по запросам — около 105 RPS. Но, если посмотреть на среднюю, видно, что это где-то около 50 RPS. Соответственно, у нас получились следующие выводы. 

  • 99-й перцентиль у нас 1968 миллисекунд,

  • 95-й перцентиль — около 800 миллисекунд,  

  • общее число запросов в минуту — это около 6300. 

Это более или менее коррелируется с тем, что мы посчитали в самом начале. Полученные результаты мы перевели в понятную форму, чтобы принести бизнесу и потребовать увеличения мощности. 

  • Предел для нас — это 70 потоков на один под. Больше перебороть не можем. Дальше умрем. 

  • Стабильность работы системы около 20 потоков. Еще она более или менее удобоваримая. Да, часть виджетов не отдается, но они не самые важные для бизнеса. Бизнес устроило такое поведение системы. 

Вспомним первый скрин из поста по текущей нагрузке и посчитаем нагрузку, которую нам готовы предоставить с промоакций. Я напомню, что это 40 тысяч клиентов. Рассчитываем, что нагрузка будет происходить в течение вот этих самых 12 часов. Таким образом, у нас получается, что на один под прибавится 8 человек в минуту. На 7 подов около 56 человек. Рассчитываем, какая приблизительная нагрузка будет в RPM, получаем около 900–500. 

Да, синтетическая нагрузка показала, что плюс-минус где-то под потолок мы, скорее всего, выдержим. Но никто не хочет рисковать продом перед крупной акцией. Тем более MVP выпустился в такой большой поток, а мы можем получить определенные плюшки на свой проект. Следовательно, нагрузка должна увеличиться где-то около двух раз для одного пода. 

Какие сделали решения на проекте 

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

Второе — нужно срочно кэшировать картинки и популярные запросы. 

Итог

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

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

Еще нужно собирать мониторинги — технические и бизнес-мониторинги, очень тщательно. Почему? Потому что если бы я их собирал вначале, я бы увидел, что нагрузка уже растет, и нужно как можно быстрее пинать людей, чтобы они сдавали проект в эксплуатацию, либо задумывались о том, что нам нужно нагрузочное тестирование. И чтобы мы как-то это уже начали планировать загодя. Собственно, по бизнес-метрикам и трафику это можно было понять где-то за месяца полтора. А следовательно, это лишнее время. 

Ну и какой следующий совет я для себя выведу? Нужно быть активным. Думайте, сотрудничайте с разработкой, аналитикой и бизнесом. 

© Habrahabr.ru