Нагрузочное тестирование веб-проекта — без купюр

    Друзья, добрый день!

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

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


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

    • запросы к MySQL (дальше будем приводить в пример эту популярную базу данных) идут через достаточно адекватное API, использующее индексы (хотя как именно используются индексы планировщиком, какова их кардинальность, мы не видим)
    • результаты выполнения запросов к БД и тяжелых кусков кода — кэшируются
    • разработчик 3.14 раза проверил построение веб-страницы в браузере и если на «глаз» не тормозит, то все ОК

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

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

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

    Аналогичная ситуация с запросами к MySQL. Если запросы выполняются по индексам, то, в общем случае, запросы будут выполняться… «быстрее». Можно верить, что время выполнения таких запросов логарифмически зависит от объема данных (O(log(n))). Но на практике часто оказывается, что одни запросы влияют на другие, используя одновременно общие подсистемы БД (сортировка на диске, который начинает тормозить) и сразу предвидеть это — нельзя.

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

    Иногда забывают установить в MySQL путь для временных таблиц на диск, отображающий данные в оперативную память ("/dev/shm"), из-за чего при возрастании нагрузки сервер БД ложится от интенсивных сортировок.

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

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

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


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

    • Сделан 1 млн. хитов. Среднее время построения веб-страницы = 1 сек. Что это показывает? Да ничего. Сколько длилось нагрузочное тестирование? Время выполнения отдельного запроса может быть как 1 мс, так и 600 секунд и непонятно, в каких пропорциях чего больше. И сколько было ошибок при этом (ответ nginx в стиле «Ошибка 50х») — тоже непонятно :-)
    • Сделан 1 млн. хитов. Медиана времени построения веб-страницы = 1 сек, число HTTP-ошибок — 0.5% Что это показывает? Пока еще немного полезного, но уже получше. Долю неадекватных ошибок, которое может словить клиент, мы уже знаем, что прекрасно и можно начать готовиться и сходить в аптеку. Медиана — более устойчивая к «выбросам» метрика, чем среднее (более «робастная» оценка), поэтому она, несомненно, лучше средней арифметической. Но давайте сделаем метрики еще полезнее.
    • За сутки сделан 1 млн. хитов. 25% хитов сделаны менее, чем за 10 мс, 50% хитов сделаны менее, чем за 1 сек (это и есть медиана или 50 процентиль), 75% хитов сделаны менее, чем за 1.5 сек, 95% хитов сделаны менее, чем за 5 сек и число HTTP-ошибок — 0.5% Самое то! Долю неадекватных ошибок, которое может словить клиент, мы видим, но также мы видим доли запросов, которые выполняются более определенного порога.

    Как видим, выбор адекватных метрик для оценки скорости работы веб-проекта при нагрузочном тестировании — очень и очень важен. Принцип один — метрики должны быть абсолютно понятны и клиенту и вам и хорошо и ясно показывать качество. По сути, самая наглядная и правильная метрика — это распределение скорости обработки хитов по времени. Если получится такую сделать на вашем нагрузочном тестировании — будет супер. Более того, можно сравнивать 2 нагрузочных тестирования по характеру распределения времени хитов и видеть: как стало лучше и где. Визуализация — сила!

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


    Все просто! Сейчас нарисую и покажу в прекрасной среде для анализа данных: Jupyter notebook/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-файла:



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



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







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


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

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

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

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



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



    Чем это обусловлено? Часто сверху забывают забивают ограничить число apache или потоков запросов к МySQL, что вызывает выпадение приложений из оперативной памяти в медленный своп с конвульсиями:



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



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





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

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


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

    • лог запросов к nginx с временем запроса клиента (в данном случае это будет нагрузочный софт), временем проксирования от nginx к apache/php-fpm
    • лог ошибок nginx
    • лог запросов apache/php-fpm с временем обработки запроса и статусом HTTP-ответа
    • лог ошибок apache/php-fpm
    • лог медленных запросов MySQL
    • лог ошибок MySQL

    Дополнительно, должы быть аналитические графики за прошедшие сутки по использованию CPU, дисков, MySQL, ОЗУ, воркеров apache и т.д. (см. выше примеры графиков munin).

    Имея эти артефакты, вы можете, используя простой awk-скрипт в начале поста, построить распределения (гистограммки) по этим логам и посчитать число и типы HTTP-ошибок. По сути, вы можете сформировать очень емкий и полезный для бизнеса и принятия решений отчет об успешности нагрузочного тестирования примерно такого содержания:
    В течение суток сделан 1 млн. хитов. 25% хитов сделаны менее, чем за 50 мс, 50% хитов сделаны менее, чем за 0.5 сек (медиана), 75% хитов сделаны менее, чем за 1 сек, 95% хитов сделаны менее, чем за 5 сек, число ошибок HTTP — 0.01%. Тестовые данные: каталог, пользователи, новости, статьи были залиты в объеме, приближенном к ожидаемому. Один разработчик — застрелился.

    Нагрузочные цепочки:

    Главная — Новости — Детальная новости = 50%
    Главная — Обзор каталога — Детальная каталога = 30%
    Детальная каталога — Обзор каталога — Детальная каталога = 15%
    Результаты поиска — Детальная каталога = 5%

    Графики использования ресурсов серверов:

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

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

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


    Кстати да, мы не осветили этот момент. Из банальных причин обычно всплывает отсутствие балансировки между nginx — apache — mysql воркерами. Т.е. воркеры сверху не ограничивают, в результате в apache может подняться сразу 500 воркеров (каждый иногда по 100 МБ) и на MySQL прийдут сразу 500 потоков с запросами — что вызовет всплеск HTTP 50х ошибок и возможный коллапс.

    Тут рекомендуется ограничить число apache/php-fpm воркеров до числа, умещающегося в ОЗУ и, аналогично, ограничить число потоков на MySQL, для защиты от переполнения доступной оперативной памяти. Идея проста — пусть клиенты ждут перед nginx, немного может замедляясь на асинхронных и неблокирующих TCP/IP сокетах, чем «ломятся» сразу в apache/MySQL.

    Из более неприятных причин тут может быть segfault PHP. В этом случае необходимо включить сбор coredump и с помощью gdb посмотреть, почему это происходит. В большинстве случаев через обновление/конфигурацию PHP проблему удается обойти.

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


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

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

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

    Итоги и выводы


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

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

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

    Удачи, друзья и задавайте вопросы в комментариях!
    1С-Битрикс
    73,54
    Компания
    Поделиться публикацией

    Комментарии 29

      +1
        +1
        И? :-)
          0
          В статье про нагрузочное тестирование не написано, как его проводить.
          А эта ссылка делает статью хоть немного полезной.
            +1
            Так можно без танка же, мало просто кто об этом знает :-)
              0
              Можно. Но в статье об этом ни слова.
                0

                Кто-то знает о танке, но не знает об ab?

        • НЛО прилетело и опубликовало эту надпись здесь
            +1
            Каждый день читаю ТЗ на веб-сайты, постоянно участвую в крупных корпоративных внедрениях веб-кластеров и редко кто серьезно задумывается о нагрузочном тестировании, поверьте. Пытаюсь привлечь внимание к проблеме простыми словами.
            • НЛО прилетело и опубликовало эту надпись здесь
              +1

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


              А что до ТЗ, то даже если оно есть, ну или что-то на него похожее, то о нагрузке там ничего, ну а если есть какие то rpm то проверяются они запуском ab на главной, или на каком-то ендпоинте апи

              +3
              Хорошая статья, все лаконично описано. Хотел бы привлечь внимание к моменту имитации реальных пользователей. Стоит сказать, что реально имитировать действия пользователей просто паузами — недостаточно. Там много всяких нюансов начиная от невозможности воспроизвести реальный партерн их поведения, заканчивая куками, спецификой браузеров и операционок. Все это — высокая стоимость НТ, которая дает низкий профит. Если виртуальные пользователи будут вести себя один в один как реальные, для имитации, например десятысечной аудитории вам потребуется либо одна очень хорошая машина, либо несколько, но похуже, 10к потоков, с большим количеством логики и параметризации, которые не редко приводят к утечке памяти на генераторах. Хорошая практика — исследование поведения и сценариев реального влияния на нагрузку системы. Допустим, если для системы однобоко количество коннектов — можно реализовать нагрузку 10к пользователей сотней суперпроизводительных. Если системе не важно, что придет в параметре, то и параметризировать его нужно в зависимости от важных показателей — в случае если параметр пишется в БД как коммент, например, можно пренебречь его семантикой и генерить рандомно — проще, а главное дешевле. В погоне за «реальными пользователями» заказчики платят дорого, а нагрузочники страдают от задач, связанных с утилизацией ресурсов, оптимизацией скриптов, написанием трушных генераторов и прочий околоНТшный треш. В большинстве своем веб тестируется тпсами/сценариями, которые параметризованны в соответствии с рисками кэширования и распределениями в БД — минимально. Таким образом дешево, легко поддерживается, быстро и легко пишется — а результаты в сравнении с мучениями относительно тру юзеров, чаще всего, аналогичны.
              • НЛО прилетело и опубликовало эту надпись здесь
                  +1
                  Согласен, искусственные паузы между запросами и стремление к реальным пользователям за счет таких пауз увеличивают шаг нагрузки. Что и потребуют больше потоков при наличии требования к заданной интенсивности. Что часто приводит к ситуации 10к тредов.

                  Но у автора 20 тредов. Закрытая модель нагрузки. Фактически, интенсивность он напрямую не контролирует. А раз так, то можно добавлять любые паузы.

                  Профиль нагрузки
                  image

                  image


                  Минус отсутствия контроля за интенсивностью является то, что первоначальное требование
                  За сутки сделан 1 млн. хитов

                  проверить уже невозможно. Будет сделано столько хитов, сколько выдадут 20 пользователей, которые работают в течение 86400 сек (24 часа). И тут может получиться, как 10 млн, так и 100 тысяч. Зависит от времени отклика системы и длительности пауз.
                    +1
                    Смотрите, видимо не совсем ясный слайд в пост вставил, сейчас поясню:
                    — шаги цепочки известны, цепочек (thread groups) несколько
                    — матожидание паузы между хитами, с учетом рандомности, тоже известно
                    В итоге мы знаем «в среднем» продолжительность хитования одной цепочки и число хитов в ней как в секунду, так и, разумеется, в сутки. Цепочки в первоначальном плане у нас разделяются на доли: 30%, 20%, 45%, 5%, которые фактически являются вероятностями появления той или иной цепочки или, другими словами, пользователя в группе хитующих пользователей. В результате все данные, для рассчета примерно миллиона хитов в сутки у нас есть. Сам расчет на выходе дает число потоков в каждой thread group и выполняется в эксельке.
                    Рассмотрим пример:

                    Цепочка А: хит, пауза 1 сек, хит, пауза 2 сек, хит
                    Длина: 3 хита
                    Время выполнения: ~3 сек

                    Цепочка Б: хит, пауза 1 сек, хит
                    Длина: 2 хита
                    Время выполнения: ~1 сек

                    Распределение цепочек, скажем, 60% А и 40% Б. И за сутки нам нужно получить примерно миллион хитов.

                    Цепочка А за секунду генерит 1 хит. Цепочка Б за секунду генерит 2 хита. В сутки цепочка А создаст 86400 хитов, а цепочка Б — 86400*2 = 172800 хитов.

                    Т.к. мы изначально разделили пользователей на группы с долями 60% и 40%, а каждый нагрузочный поток есть полный аналог пользователя, то в каждый момент времени, 60% нагрузочных потоков должны выполнять цепочку А, а 40% потоков — цепочку Б.

                    0.6 * N * (1 хит/сек) * 86400 + 0.4 * N * (2 хита/сек) * 86400= 1 000 000 хитов за сутки

                    Найти N — легко! Тут можно еще дальше порассуждать и поискать скажем N, при котором в миллионе хитов в сутки доля цепочки А будет 60%, а доля цепочки Б — 40%, но для простоты вариант, когда число нагрузочных потоков пропорционально доле цепочки — работает хорошо.

                      +2
                      Понял подход. Можно гибче сделать. С одной катушкой и Throughput Controller-ами для блоков.

                      Тогда чтобы поднять нагрузку достаточно просто увеличить количество потоков в одной катушке и ничего не придётся пересчитывать в Excel. Это количество потоков удобно передавать в скрипт из вне. Взяв в качестве значения не константу 20, а property
                      ${__P(NUM_THREADS, 20)}, которое уже задавать в параметрах запуска скрипта:


                      А чтобы не считать матожидания и, главное, не пересчитывать их в Excel при модификации скрипта. Можно просто положиться, что запрос выполняется не более 5 сек. И это значение можно сразу выставить в

                      HTTP Request Defaults: Response Timeout (4000) и Connect Timeout (1000)

                      И зная, что каждый запрос не более 5 сек. Рассчитать с округлением длительность всего сценария по верхней планке: пусть 50 запросов, значит 50*5=250 сек, а если с запасом, то 300 сек.

                      Чтобы не валить сервер, когда время отклика превысит 5 сек на запрос. Стоит поменять в катушке параметр Action to be taken after a Sampler error со значения Continue на значение Start Next Thread Loop.

                      После чего можно выставить шаг нагрузки. В 300 сек (6 минут). Используя Constant Througthput Timer:
                      • Target Throughput (1/6): 0.1667
                      • Calculate Throughput based on: this thread only

                      Посчитаем сколько запросов будет за сценарий:
                      • Авторизация — 10 запросов — вероятность 1.0
                      • Главная — 30 запросов — вероятность 1.0
                      • Календарь — 20 запросов — вероятность 0.2
                      • Блог — 70 запросов — вероятность 0.1
                      • Файлы — 15 запросов — вероятность 0.05


                      Получилось, примерно:

                      10 * 1.0 + 30 * 1.0 + 20 * 0.2 + 70 * 0.1 + 15 * 0.05 = 51,75

                      А количество потоков в катушке рассчитать так, чтобы получился требуемый 1 млн запросов в 24 часа:
                      • 1 000 000 / 51,75 запросов / 24 часа / 60 минут == 13,419216318 запусков сценария в минуту нужно сделать для интенсивности 1 млн в день
                      • 0.1667 запусков сценария в минуту делается сейчас одним потоком
                      • значит 13,419216318 / 0.1667 == 80,499198068 ~ 81 поток нужен


                      Примерный размер пула потоков мы нашли.

                      Так как значение 81 не очень большое, не 10к. То можно доверить финальный расчёт интенсивности умным таймерам. Добавив в пул не менее 81 поток. Например для постоянной нагрузки хорош точный таймер: Precise Throughput Timer.

                      Настроек у него немало. Но нам в общем понадобятся такие:
                      • Target throughput (in samples per 'throughput period'): 1000000
                      • Throughput period (seconds): 86400
                      • Test duration (seconds): 86400

                      А в катушке нужно будет по прежнему задать не менее 81 поток, но плюс в том, что можно задать и больше. Например, 500. Таймер умный, и использует столько, сколько надо, чтобы получилась интенсивность 1 000 000 в сутки. А когда пул взят с запасом. То можно долгое время не пересчитывать нагрузку в Excel. Просто дорабатывать скрипт, добавлять в него запросы.

                      Про паузы. Precise Throughput Timer сам сделает паузы между запросами. Может сделать их случайными. И добавлять паузы искусственно не придётся.

                      В теории это так работает. Но, конечно, надо всё проверять.
                        +1
                        vladimirsitnikov привет. Прорецензируй пожалуйста комментарий. Верно ведь указал сферу применения таймера Precise Throughput Timer и его параметры?
                    0
                    Спасибо! Да, действительно интересно, задумался.
                    +2
                    Отличный awk-скрипт. Тоже их люблю.

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

                    Например, в статье есть действия:
                    1. Авторизация
                    2. Главная
                    3. Задачи
                    4. Календарь
                    5. Файлы
                    6. Фотографии
                    7. ...


                    Для стандартного формата access.log ngxin:
                    стандартный формат
                    log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';


                    где поле '"$request" обрамлено двойными кавычками, поэтому если в качестве разделителя использовать двойную кавычку, то значение поля $request будет после первой и до второй двойной кавычки. То есть $request будет $2 элементом после разделения строки.

                    Пример:
                    127.0.0.1 - - [16/Jun/2019:21:30:16 +0300] "GET /icons/ubuntu-logo.png HTTP/1.1" 404 152 "http://localhost/" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:67.0) Gecko/20100101 Firefox/67.0"



                    Можно использовать такой скрипт, чтобы посмотреть распределение операций:

                    (cat /var/log/nginx/access.log && cat /var/log/nginx/access.log.1 && zcat -qa /var/log/nginx/access.log.*.gz ) | awk -F '"' '{a[$2]++}END{n=asort(a,b);aMax=b[n];for(i in a){print a[i] " --- " (a[i] / aMax) " --- "  i}}' | sort -nr


                    Статистика, нормированная по самой частой операции. Как правило, самая частая операция — главная и авторизация.

                    И по полученной статистике вида
                    11 --- 1 --- GET /icons/ubuntu-logo.png HTTP/1.1
                    11 --- 1 --- GET / HTTP/1.1
                    1 --- 0.0909091 --- GET /favicon.ico HTTP/1.1


                    Настроить, используя компонент Throughput Controller, вероятности для блоков. И получится, что «Авторизация» и «Главная» имеют вероятность 1.0, а «Фотографии» и «Блог» имеют вероятность 0.0909091.
                      +1
                      спасибо, интересно!
                      +2
                      Спасибо за статью. Очень понравился раздел «Интерпретация результатов нагрузочного тестирования», где отмечена важность анализа логов.

                      Технический вопрос про bitrix24. В скрипте нагрузка подаётся минимум на 250 серверов
                      load[1...250].bitrix24.[строки из csv-файла]
                      По факту, думаю, речь идёт про 500, 1000 серверов.
                      Это большая ферма.

                      Скриншот, где показан профиль нагрузки в 20 потоков и скриншот, где показан один график утилизации CPU, DISK,… тут показаны для примера? А реальная нагрузка подаётся с такой же большой фермы генераторов нагрузки (100 штук)?

                      Ещё. При таком большом количестве доменных имён есть смысл использовать DNS Cache Manager. Если интенсивнсть большая. Ведь по умолчанию JMeter не кеширует DNS-ответы, а клиенты (браузеры) кешируют. И на практике, это однажды ограничило нагрузку. Что стало сюрпризом. Ведь редко кто мониторит и DNS-сервер во время нагрузки.
                        0
                        Спасибо. Технически графики нагрузки я взял из другой системы, чем цепочки. Jmeter да, можно кластеризовать на несколько машин, но обычно одной хватало.
                          +1
                          А всё-таки, на сколько серверов подаётся нагрузка? На 250+?
                            0
                            нет, намного меньше :-)
                            • НЛО прилетело и опубликовало эту надпись здесь
                                0
                                Цитата из статьи
                                Коню ясно, что нельзя при нагрузочном тестировании дергать только одну детальную страницу каталога, поэтому полезно считывать и ротировать их список из CSV-файла:
                                image

                                image



                                Так как domain_name принимает значение от 1 до 250. А domain_l1_name ещё несколько значений, пусть 2. То всего имён серверов будет 250 * 2 = 500.
                                В статье нагрузка подаётся на 500 серверов. Они принимают нагрузку. Судя по тексту статьи
                                Кстати да, мы не осветили этот момент. Из банальных причин обычно всплывает отсутствие балансировки между nginx — apache — mysql воркерами.

                                нагрузку принимают nginx-узлы.

                                Отвечая на вопрос
                                уточните, пож-та, какой сервер Вы имели ввиду, если указаны несколько в многозвенной системе: proxy, web, app, db (возможно ещё balancer, а в отказоустойчивой схеме и т.д.)?

                                имел в виду nginx, предполагая, что нагрузка подаётся на него. Он физически может быть один (один сервер), но обслуживать 250 или 500 доменных имён или даже 1000. Правила перенаправления позволяют написать любую конфигурацию.

                                Конфигурация необычная. Поэтому и задал свой вопрос автору. Автор ответил, что серверов намного меньше, чем 250.

                                и какая суть разницы фигачить соответствующей нагрузочной интенсивности поток запросов на 1 (или 1 сбалансированный отказоустойчивый контур многозвенки) или 250+?

                                Разница в мелких деталях. Так подавая нагрузку на 250, 500, 1000 доменных имён. И не включив кеширование DNS ответов на JMeter. Мы будем активнее опрашивать DNS-сервер, на котором будет немалая таблица адресов. Он будет испытывать нагрузку и может стать узким местом. На что обратил внимание автора.
                                В случае 1 доменного имени ситуация упрощается, нагрузка на DNS меньшая.

                                Если за указанными 250, 500, 1000 доменными именами стоит столько же разных ip-адресов, то гораздо меньше шансов достигнуть лимита соединений между клиентом и сервером. Так как серверов много и лимиты на количество подключений не будут достигнуты. Если же сервер соотвествует 1 ip-адресу, и клиент соотвествует тоже только 1 ip-адресу. То при высокой интенсивности узким местом может стать получение подключения от клиента к серверу на генераторе нагрузки. По простому — JMeter, имитирующий интенсивную работу 1000 пользователей, не сможет создать ту же нагрузку, что и 1000 пользователей работающих с разных ip-адресов. Об этом рассказывал на конференции Гейзенбаг.

                                Ускоряем Apache.JMeter:

                                Тут детали почему так происходит, и как можно настроить нагрузочную станцию.
                                • НЛО прилетело и опубликовало эту надпись здесь
                                    0
                                    Не замерял никогда ещё.
                                    Изучил вопрос немного.

                                    Получается, что Java по умолчанию хранит кеш успешных адресов с момент старта до момента завершения. А кеш неуспешных хранит 10 сек.
                                    $JAVA_HOME/jre/lib/security/java.security
                                    #
                                    # The Java-level namelookup cache policy for successful lookups:
                                    #
                                    # any negative value: caching forever
                                    # any positive value: the number of seconds to cache an address for
                                    # zero: do not cache
                                    #
                                    # default value is forever (FOREVER). For security reasons, this
                                    # caching is made forever when a security manager is set. When a security
                                    # manager is not set, the default behavior in this implementation
                                    # is to cache for 30 seconds.
                                    #
                                    # NOTE: setting this to anything other than the default value can have
                                    # serious security implications. Do not set it unless
                                    # you are sure you are not exposed to DNS spoofing attack.
                                    #
                                    #networkaddress.cache.ttl=-1

                                    # The Java-level namelookup cache policy for failed lookups:
                                    #
                                    # any negative value: cache forever
                                    # any positive value: the number of seconds to cache negative lookup results
                                    # zero: do not cache
                                    #
                                    # In some Microsoft Windows networking environments that employ
                                    # the WINS name service in addition to DNS, name service lookups
                                    # that fail may take a noticeably long time to return (approx. 5 seconds).
                                    # For this reason the default caching policy is to maintain these
                                    # results for 10 seconds.
                                    #
                                    #

                                    networkaddress.cache.negative.ttl=10



                                    В файле system.properties эти настройки не переопределены.
                                    apache-jmeter-5.1/bin/system.properties
                                    # Java networking-related properties
                                    #
                                    # For details of Oracle Java network properties, see for example:
                                    # http://download.oracle.com/javase/1.5.0/docs/guide/net/properties.html
                                    #
                                    #java.net.preferIPv4Stack=false
                                    #java.net.preferIPv6Addresses=false
                                    #networkaddress.cache.ttl=-1
                                    #networkaddress.cache.negative.ttl=10



                                    Получается, что DNS Cache Manager не нужен для ускорения. А может он понадобиться наоборот, чтобы сбрасывать кеш.



                                    А доля DNS Lookup, если сервер верно настроен, будет небольшой.
                                    Но был случай, он помог. Теперь не могу объяснить почему. Спасибо за вопрос.
                                    • НЛО прилетело и опубликовало эту надпись здесь
                          0
                          постоянно вскрывают битрикс и ставят редирект на порносайты.
                          раньше майнер втыкали. удалять шеллы устали.

                          кому подешевке продать лицензию битрикс бизнес?

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

                          Самое читаемое