JMeter — швейцарский нож тестировщика (Часть 1)


Поговорим о JMeter’е? Скорее всего, если вы в теме, то давно уже прочли всё об этом инструменте для нагрузочного тестирования. Но мне есть чем вас удивить. За три года работы в QA я понял, что JMeter очень универсален и может использоваться в самых разных целях. Например, для:

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

Если заинтересовались — добро пожаловать под кат. Получилось объемно, поэтому разобью статью на две части.

Disclaimer: По понятным причинам я не вставляю в статью скриншоты из реальных проектов (или вымарываю из них всю важную информацию). Иллюстрации представлены исключительно в исследовательских и ознакомительных целях.

Классическое применение JMeter


JMeter — Java-апплет с GUI. Для тестирования он запускается без графического интерфейса. А для написания тестовых скриптов у него панель, в которой можно сделать всё что угодно.

Создание скрипта на JMeter
Так выглядит процесс создания скрипта (тут даже слово «написания» не подойдет)

Создается общий Test Plan, в который закидывается Thread Group с основными элементами теста: контроллеры, управляющие процессом, и запросы (HTTP, FTP и т.д.).

Помимо этого есть дополнительные элементы для задания параметров. Например, HTTP Request Defaults позволяет указать основной сервер, заголовки и включить/выключить загрузку дополнительных ассетов (картинок, стилей, шрифтов и прочего). Разобраться несложно. А ещё можно сразу из этого интерфейса запустить тест и посмотреть на результаты.

JMeter умеет записывать такие тестовые сценарии. Он запускается в виде прокси на локальной машине и, если вы настроите браузер (или приложение), вести трафик через эту проксю. JMeter запишет все запросы и ответы. А из этого набора можно состряпать тестовый сценарий, который будет повторять действия пользователя, и запустить его где и когда угодно:

Запись скрипта в JMeter исходя из действий пользователя


Основная проблема — heap памяти самой Java. Он упирается в потолок и может упасть при 50 потоках одновременного тестирования даже на топовых машинах.
Если для проведения полного нагрузочного тестирования мощности машины не хватает — обратитесь к сторонним организациям. Они развернули у себя инфраструктуру, являющуюся набором серверов. На них поднят тот же самый JMeter. За вознаграждение эти ребята запустят ваш скрипт у себя на любой нагрузке. Мы обращались за такими услугами в Octoperf и Blazemeter.

Это футбол, детка: как мы ловили баг с частичным падением сервера


Мы занимаемся веб-разработкой 18 лет (ура — теперь можно курить, жениться и смотреть «Джона Уика»). Клиентов на своём веку повидали немало, но самые крупные появились недавно. Один из них — британский футбольный клуб Southampton FC.

Мы разработали для них новый сайт на Sitecore с парадигмой SPW (single page website: все страницы открываются без перезагрузки самой страницы браузера). Под капотом — админка для управления страницей живого матча. Это текстовая онлайн-трансляция игры: основные события (голы, удаления, штрафные удары) подгружаются автоматически из системы Opta, а фото, комментарии и репосты болельщиков из Twitter и Instagram публикуют живые люди — контент-менеджеры Southampton FC.

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

Перед запуском мы провели полное нагрузочное тестирование и убедились, что всё работает как надо. Структура серверов выглядела так:

  1. запрос от клиента идёт на сервер распределения нагрузки >
  2. сервер распределения нагрузки проверяет состояние восьми CD-серверов >
  3. сервер распределения нагрузки направляет запрос на наименее нагруженный CD-сервер >
  4. CD-сервер отвечает клиенту.

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

— У нас сайт не работает! Вообще не работает! Просто белый экран и надпись от браузера, что сайт не работает! — говорит клиент.
Мы в панике открываем сайт, а с ним все ОК:
— Всё же работает, — отвечаем.
Клиент открывает сайт с телефона и компьютера и… у него тоже все ОК!
— Действительно, извините. Видимо, у юзеров проблемы.

Такие сообщения на пустом месте не появляются, поэтому мы провели исследование: запустили Server Density и отследили состояние серверов Southampton FC во время наплыва пользователей:

Просмотр истории нагрузки серверов в инструменте Server Density
Нагрузка есть, но все CD-сервера выглядят примерно одинаково и ровно

Скоро история повторилась — часть пользователей сообщили о полностью неработающем сайте. Это была не какая-то ошибка или ненайденная страница — сервер просто не отвечал на запрос. Отловить ситуацию получилось с помощью JMeter’а.

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

Самый простой скрипт нагрузочного теста в JMeter с запросом одной страницы в цикле

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


Скрипт начал загружать новые картинки и другие ассеты, что нагрузило сервера достаточно для проведения эксперимента

Тут выяснилось, что Server Density сглаживает данные за прошлые периоды. Если за пять минут нагрузка на сервер достигла 100%, потом упала до 0%, а через 20-30 секунд выросла до 90%, он покажет среднее значение за этот период — около 80-90%. Поэтому мы и не видели реального падения серверов.

Детально разобрав логи во время стресс-тестов, мы выяснили, что один из CD-серверов при стопроцентной загрузке уходил в ребут и никому об этом не сообщал (вот такой он интроверт).



Сервер распределения нагрузки смотрел только на загрузку CPU всех серверов. Он видел, что один из них загружен на 20%, а остальные — под 90%, и отправлял юзера на первый. А он находился в ребуте и выдавал белый экран. Кроме того, сервер распределения выставлял юзеру куку и намертво привязывал его к неработающему серверу. Поэтому даже после обновления сайт был недоступен. Остальные 7 из 8 юзеров при этом радовались жизни и говорили, что все работает.

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

Вывод:

JMeter — удобный инструмент для проведения стресс-тестов и одновременного анализа состояния серверов сторонними инструментами.

В следующей части расскажу, как мы с помощью JMeter’а наладили процесс кэширования продуктовых страниц, проверили работу мобильного приложения без самого приложения и создали 2000 юзеров в системе без доступа к базе данных.




К сожалению, не доступен сервер mySQL