Как стать автором
Обновить

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

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

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

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

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


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

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

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

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

image


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

проверить уже невозможно. Будет сделано столько хитов, сколько выдадут 20 пользователей, которые работают в течение 86400 сек (24 часа). И тут может получиться, как 10 млн, так и 100 тысяч. Зависит от времени отклика системы и длительности пауз.
Смотрите, видимо не совсем ясный слайд в пост вставил, сейчас поясню:
— шаги цепочки известны, цепочек (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%, но для простоты вариант, когда число нагрузочных потоков пропорционально доле цепочки — работает хорошо.

Понял подход. Можно гибче сделать. С одной катушкой и 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 сам сделает паузы между запросами. Может сделать их случайными. И добавлять паузы искусственно не придётся.

В теории это так работает. Но, конечно, надо всё проверять.
vladimirsitnikov привет. Прорецензируй пожалуйста комментарий. Верно ведь указал сферу применения таймера Precise Throughput Timer и его параметры?
Спасибо! Да, действительно интересно, задумался.
Отличный 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.
спасибо, интересно!
Спасибо за статью. Очень понравился раздел «Интерпретация результатов нагрузочного тестирования», где отмечена важность анализа логов.

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

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

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

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

Получается, что 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, если сервер верно настроен, будет небольшой.
Но был случай, он помог. Теперь не могу объяснить почему. Спасибо за вопрос.
НЛО прилетело и опубликовало эту надпись здесь
постоянно вскрывают битрикс и ставят редирект на порносайты.
раньше майнер втыкали. удалять шеллы устали.

кому подешевке продать лицензию битрикс бизнес?
Зарегистрируйтесь на Хабре , чтобы оставить комментарий