Нагрузочное Тестирование Веб-Проекта – Без Сокращений

Друзья, добрый день! Продолжаем серию «неразрезанных» публикаций о проектах, связанных с разработкой, часто с приставкой «веб».

Поговорим сегодня о нагрузочном тестировании.

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

бизнес.

Нальём кофе и пойдём.



Зачем нужно нагрузочное тестирование веб-проекта?

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

Увидеть веб-проект одновременно с автоматическими тестами и тестами кода очень редко.

Гораздо чаще и по разумным причинам при разработке придерживаются следующих эвристик, имеющих хорошее соотношение выгод и затрат:

  • запросы к MySQL (в качестве примера мы будем использовать эту популярную базу данных) проходят через вполне адекватное API, использующее индексы (правда, мы не видим, как именно индексы используются планировщиком, какова их мощность)
  • кэшируются результаты выполнения запросов к базе данных и тяжелые куски кода
  • разработчик проверил построение веб-страницы в браузере 3,14 раза и если на глаз не тормозит, то все ок
«Вристика часто работает хорошо, но чем крупнее и загруженнее проект, тем больше может пойти не так с экспоненциально возрастающей вероятностью.

Возьмем кеширование.

Во время разработки часто нет времени думать о том, как часто можно пересобирать кэш.

Но тщетно.

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

Именно поэтому, кстати, не рекомендуется использовать встроенный кэш запросов MySQL, который страдает аналогичной проблемой: при изменении хотя бы одной записи таблицы кэш таблицы полностью сбрасывается (представим себе таблицу из 100к строк и абсурдность ситуации становится очевидной).

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

"быстрее".

Можно поверить, что время выполнения таких запросов логарифмически зависит от объема данных (O(log(n))).

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

Также под нагрузкой часто выявляются интересные особенности операционной системы, в частности, переполнение диапазона исходящих клиентских TCP/IP-портов при интенсивной работе с memcached. Либо апач забит запросами на обработку изображений, потому что.

При настройке забыли настроить их обработку кеширующим прокси-сервером nginx. Иногда люди забывают указать путь для временных таблиц в MySQL к диску, отображающему данные в ОЗУ («/dev/shm»), из-за чего сервер базы данных перегружается интенсивной сортировкой по мере увеличения нагрузки.

Также при добавлении данных в веб-проект в объеме, близком к боевому, запросы и алгоритмы начинают агрессивно отображать свою «О-нотацию»: если для небольшого объема данных декартова невидима, то при появлении боевого объема , сервер базы данных краснеет от напряжения.

Можно привести еще много примеров, но остановимся пока на этом.

Главное понимать, что нагрузочное тестирование необходимо.

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



Как установить цели нагрузочного тестирования?

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

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

  • Сделано 1 миллион просмотров.

    Среднее время создания веб-страницы = 1 секунда.

    Что это показывает? Неважно.

    Как долго длилось нагрузочное тестирование? Время выполнения одного запроса может быть как 1 мс, так и 600 секунд, причем непонятно, в каких пропорциях что больше.

    И сколько было ошибок (ответ nginx в стиле «Ошибка 50х») тоже неясно :-)

  • Сделано 1 миллион просмотров.

    Среднее время создания веб-страницы = 1 секунда, количество ошибок HTTP — 0,5%.

    Что это показывает? Все еще немного полезно, но лучше.

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

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

    Но давайте сделаем метрики еще более полезными.

  • За один день было сделано 1 миллион просмотров.

    25% обращений выполняются менее чем за 10 мс, 50% обращений выполняются менее чем за 1 секунду (это медиана или 50-й процентиль), 75% обращений выполняются менее чем за 1,5 секунды, 95% обращений выполняются менее чем за 1,5 секунды.

    делается менее чем за 5 секунд, а количество ошибок HTTP составляет 0,5% Вот и все! Мы видим долю неадекватных ошибок, которые может отловить клиент, но также видим долю запросов, которые выполняются выше определенного порога.

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

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

На самом деле, самая наглядная и правильная метрика — это распределение скорости обработки обращений во времени.

Если вы сможете сделать это во время нагрузочного тестирования, это будет здорово.

Более того, вы можете сравнить 2 нагрузочных теста по характеру распределения времени попадания и посмотреть, как и где дела обстоят лучше.

Визуализация – это сила!

Ничего не понятно: процентили, медианы, квантили, графики, распределение.

Это просто! Сейчас я его нарисую и покажу в отличной среде для анализа данных: блокнот Jupyter/Python. Допустим, на сайт поступило 10 посещений за это время в миллисекундах:

Нагрузочное тестирование веб-проекта – без сокращений

Теперь отсортируем время выполнения обращений по возрастанию:

Нагрузочное тестирование веб-проекта – без сокращений

Мы находимся в одном шаге от понимания медианы, 25-го и 75-го процентилей.

Все просто — делим график пополам и посередине будет «медиана» (цифра 1 на графике).

Первая четверть графика будет соответствовать 25-му процентилю (цифра 2 на графике), а третья четверть — 75-му процентилю (цифра 3 на графике).

Соответственно получаются другие процентили (или, как их еще называют, квантили) – 90, 95, 99 и т. д.:

Нагрузочное тестирование веб-проекта – без сокращений

А вот как будет выглядеть распределение (гистограмма) времени выполнения приведенных выше хитов.

Как видите, все очень понятно и просто:

Нагрузочное тестирование веб-проекта – без сокращений

И вот так можно быстро построить распределение (гистограмму) на основе журнала запросов на нагрузочное тестирование.

Измените его в соответствии с вашим форматом журнала:

   

#!/bin/bash TOTAL=`cat /var/log/nginx.access.log | wc -l` echo "Total:" $TOTAL cat /var/log/nginx.access.log | awk -F'->' '{ $2=$2*1000; zone = int($2/100)*100; hits[zone]++; } \ END {for (z in hits) {printf("%8s ms: %8s,%6.2f% ",z,hits[z],hits[z]/total*100);{s="";a=0;while(a++<int(hits[z]/total*100)) s=s"*";print s} } }' \ total="$TOTAL" - | sort -n

И вы получите что-то вроде этого:

Нагрузочное тестирование веб-проекта – без сокращений

Надеюсь, теперь все понятно и на своих местах.

Если нет, спрашивайте в комментариях.



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

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

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



Планирование распределения нагрузки

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

Но они зачастую решают проблему загрузки только разрабатываемой веб-системы.

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

Например:

  • Главная — Новости — Подробные новости = 50%
  • Главная — Обзор каталога — Подробный каталог = 30%
  • Подробный каталог - Просмотр каталога - Подробный каталог = 15%
  • Результаты поиска - Подробный каталог = 5%
В ПО для создания нагрузки (мы часто используем Jmeter) для каждой цепочки создается столько потоков загрузки, что с учетом интервала между попаданиями в цепочку общее количество попаданий каждой цепочки в единицу времени соотносится как: 50%, 30%, 15%, 5%.

Расчет интервалов и потоков нагрузки легко сделать в Excel или на листе бумаги карандашом.



Структура грузовой цепи

Здесь важно учитывать особенности жизненного цикла пользователя веб-системы.

Часто пользователи авторизуются, а затем перемещаются по сайту.

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

Нагрузочное тестирование веб-проекта – без сокращений

Хорсу понятно, что при нагрузочном тестировании невозможно вытянуть только одну подробную страницу каталога, поэтому полезно читать и вращать их список из CSV-файла:

Нагрузочное тестирование веб-проекта – без сокращений

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

Не забудьте также о сохранении и возврате значений cookie на сервер:

Нагрузочное тестирование веб-проекта – без сокращений

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

Определенные глобальные переменные затем можно использовать в разных местах цепочек нагрузки:

Нагрузочное тестирование веб-проекта – без сокращений



Нагрузочное тестирование веб-проекта – без сокращений



Нагрузочное тестирование веб-проекта – без сокращений



Как обеспечить успешное завершение нагрузочного тестирования?

На практике почти всегда при нагрузочном тестировании крашится веб-система в первые минуты или часы, всё начинает дымить, потом горит, сайт не открывается, MySQL крашится и не даёт соединения, LA на серверах приближается к 100, разработчики стартуют бегают со словами «этого не должно было случиться», а сисадмины с ухмылкой обычно отвечают «в жизни есть справедливость!» и начнём пить пиво в серверной.

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

Я перечислю, что чаще всего происходит при сбое веб-системы и как это можно исправить.

Прежде всего, веб-сервер apache или php-fpm «забит» запросами:

Нагрузочное тестирование веб-проекта – без сокращений

Чаще всего это происходит из-за краха MySQL — увеличивается количество зависающих потоков запросов:

Нагрузочное тестирование веб-проекта – без сокращений

Что является причиной этого? Люди часто забывают ограничить количество потоков запросов Apache или MySQL, из-за чего приложения с конвульсиями выпадают из оперативной памяти и начинают медленно переключаться:

Нагрузочное тестирование веб-проекта – без сокращений

Здесь можно увидеть внезапную активность при работе со свопом, нужно разобраться, кто попал в своп и откуда:

Нагрузочное тестирование веб-проекта – без сокращений

Однако иногда проблема оказывается на стороне медленной дисковой подсистемы.

При этом LA резко возрастает и процент использования диска приближается к 100 (правый нижний график):

Нагрузочное тестирование веб-проекта – без сокращений



Нагрузочное тестирование веб-проекта – без сокращений

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

Но главное – задать правильное направление и построить правильный процесс.

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



Интерпретация результатов нагрузочного тестирования

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

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

  • лог запросов к nginx с указанием времени запроса клиента (в данном случае это будет загрузочное ПО), времени проксирования с nginx на apache/php-fpm
  • журнал ошибок nginx
  • Журнал запросов apache/php-fpm со временем обработки запроса и статусом ответа HTTP
  • журнал ошибок apache/php-fpm
  • Журнал медленных запросов MySQL
  • Журнал ошибок MySQL
Дополнительно должны быть аналитические графики за прошедший день использования CPU, дисков, MySQL, RAM, Apache Workers и т.д. (примеры мунин-диаграмм см.

выше).

Имея эти артефакты, вы сможете с помощью простого awk-скрипта в начале поста строить распределения (гистограммы) на основе этих логов и подсчитывать количество и типы HTTP-ошибок.

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

За 24 часа было сделано 1 миллион просмотров.

25% обращений менее чем за 50 мс, 50% обращений менее чем за 0,5 секунды (медиана), 75% обращений менее чем за 1 секунду, 95% обращений менее чем за 5 секунд, количество ошибок HTTP — 0,01%.

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

Один разработчик застрелился.

Грузовые цепи: Главная — Новости — Подробные новости = 50% Главная — Обзор каталога — Подробный каталог = 30% Подробный каталог - Просмотр каталога - Подробный каталог = 15% Результаты поиска - Подробный каталог = 5% Графики использования ресурсов сервера: …

Это уже хороший и понятный отчет по нагрузочному тестированию веб-системы.

Для любителей острой боли также можем порекомендовать при нагрузочном тестировании включить ежеминутный импорт-экспорт данных на сайт из систем класса SAP, 1С и т.д. и синхронные соединения через сокеты TCP/IP с внешними сервисами курсов, скажем, криптовалют :-) Но, честно говоря, если импорт-экспорт будет осуществляться аккуратно, добросовестно, то нагрузочное тестирование даже в таких условиях покажет приемлемые для бизнеса цифры.



Откуда возникают ошибки во время нагрузочного тестирования?

Кстати, да, мы этот момент не затронули.

По банальным причинам обычно всплывает отсутствие балансировки между воркерами nginx — apache — mysql. Те.

воркеры сверху не ограничены, в результате в Apache может подняться сразу 500 воркеров (иногда по 100 Мб) и в MySQL придет сразу 500 потоков с запросами - что вызовет всплеск ошибок HTTP 50x и возможное крах.

Здесь рекомендуется ограничить количество воркеров apache/php-fpm количеством, которое помещается в ОЗУ, и аналогично ограничить количество потоков в MySQL для защиты от переполнения доступной ОЗУ.

Идея проста — пусть клиенты ждут перед nginx, возможно, немного подтормаживая на асинхронных и неблокирующих сокетах TCP/IP, что приведет к их немедленному краху в apache/MySQL. Из более неприятных причин может быть сегфолт PHP. В этом случае вам нужно включить сбор дампа памяти и использовать GDB, чтобы понять, почему это происходит. В большинстве случаев обновление/настройка PHP может решить проблему.



Что осталось за кадром

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

страница во «внутренностях» Angular/React/Vue.js — поэтому не используйте тяжелый и непрозрачный, плохо протестированный фронтенд; при необходимости вы можете адаптировать грузовые цепи к этой ситуации.

В любом случае, если результаты нагрузочного тестирования бэкенда показали хорошие цифры, а сайт продолжает тормозить в браузере, уже понятно, кого «бить в наглую красную морду» :-) А если серьезно, то в следующих постах мы надеемся осветить эту важную тему.



Результаты и выводы

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

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

Для проведения нагрузочного тестирования важно привлекать не только разработчиков, но и экспертов по операционным системам и аппаратному обеспечению – опытных системных администраторов, и тогда проблемы «попадания в подкачку» или «переполнения локального диапазона IP-адресов» не возникнут. кровотечение из глаз и обморок.

Удачи вам, друзья, и задавайте вопросы в комментариях! Теги: #Управление проектами #Разработка сайтов #веб-разработка #нагрузочное тестирование

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.