Нагрузочное тестирование с использованием другого сервера

saben

New Member
Всем привет.

Хотели протестировать нагрузку используя эту документацию:
Выставлены настройки:
TTL=300
STRESSRATE=1

Версия фонера: 5.2.838

Flashphoner настроен за nginx (https://docs.flashphoner.com/pages/viewpage.action?pageId=23037753)

В целом тестирование проходит успешно, кроме одного момента.

Пошаговое описание проблемы:
0. Подготавливаем страницу для просмотра стрима. Используем embed_player (https://wcs.url/embed_player?urlSer...iders=WebRTC,Flash,MSE,WSPlayer&autoplay=true).
1. На "атакующем" сервере запускается 100 инстансов google chrome с указанием откуда смотреть стрим;
2. Проверяем количество запущенных хромов на "атакующем" сервере. Получаем 100 инстансов;
3. На атакуемом сервере смотрим в логах nginx смотрим что пришло ровно 100 запросов на страницу embed_player;
4. Смотрим статистику wcs сервера (?action=stat) и видим:
Code:
-----Connection Stats-----
connections=49
connections_rtmfp=0
connections_websocket=49
connections_hls=0
-----Port Stats-----
ports_media_free=1450
ports_media_busy=49
ports_media_quarantine=0
ports_wcs_agents_free=998
ports_wcs_agents_busy=0
ports_wcs_agents_quarantine=0
-----Stream Stats-----
streams_webrtc_in=1
streams_webrtc_out=48
Т.е. стрим сервер не запускает некоторое количество просмотров стримов. Каждый раз количество разное.
Каждая итерация тестирования проходила после хардрестарта всего софта и временного промежутка 5-10 минут.

Цифры тестирования были разные:
1. От 1 до 10 инстансов - все работает;
2. От 10 до 50 - периодически неправильное количество просмотров стримов запускается;
3. 50-150 - совпадений по количеству инстансов и "просматриваемых" стримов не совпадает в 100% случаев.

Атакующая машина по ресурсам варьировалась от: 20 ядер и 128G оперативной памяти, до 30 ядер и 128G оперативной памяти.
При запуске 150 инстансов хрома утилизация процессоров на уровне 50-60%, кроме момента запуска т.к. в тот момент утилизация была 100%.
По памяти утилизация не превышала 60% за всё время тестирования.

Инфа по процу.
Code:
vendor_id    : GenuineIntel
cpu family    : 6
model        : 85
model name    : Intel(R) Xeon(R) Silver 4114 CPU @ 2.20GHz
stepping    : 4
microcode    : 0x2006b06
cpu MHz        : 2194.843
cache size    : 14080 KB
physical id    : 38
siblings    : 1
core id        : 0
cpu cores    : 1
apicid        : 38
initial apicid    : 38
fpu        : yes
fpu_exception    : yes
cpuid level    : 22
wp        : yes
flags        : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon nopl xtopology tsc_reliable nonstop_tsc cpuid pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt tsc_deadline_timer aes xsave avx f16c rdrand hypervisor lahf_lm abm 3dnowprefetch cpuid_fault invpcid_single pti ssbd ibrs ibpb stibp fsgsbase tsc_adjust bmi1 avx2 smep bmi2 invpcid avx512f avx512dq rdseed adx smap clflushopt clwb avx512cd avx512bw avx512vl xsaveopt xsavec xgetbv1 xsaves arat pku ospke md_clear flush_l1d arch_capabilities
bugs        : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit
bogomips    : 4389.68
clflush size    : 64
cache_alignment    : 64
address sizes    : 45 bits physical, 48 bits virtual
Утилизация сети на "атакуемом" сервере не превышала 25647.16 KB/s (измерялось софтом slurm)

Вопросы в следующем: Почему так может происходить? Куда копать, чтобы понять проблему?
 

Max

Administrator
Staff member
Добрый день.

STRESSRATE=1

Выглядит слишком жестким. Каждую миллисекунду добавлять по подписчику. Скорость: 1000 подписчиков в секунду.
Попробуйте его поднять до 1000 (1 подписчик в секунду). Убедитесь, что скрипт корректно принимает значения -stressrate и -maxsubscribers
Проведите тест с вебсокет коннектом, но без стриминга. Цель теста - довести количество коннектов, например до 100 и убедиться что количество коннектов соответствует количеству запущенных инстансов. Если все упирается в 50 инстансов, попробуйте поднять 51-й инстанс хрома вручную. Возможно есть какие-то системные ограничения у "атакующего" сервера по портам, т.к. у нас на тестах также упиралось в 50 штук.
 

saben

New Member
Дело не в портах:

Вот вам пример больше числа больше 50

Code:
-----Connection Stats-----
connections=52
connections_rtmfp=0
connections_websocket=52
connections_hls=0
-----Port Stats-----
ports_media_free=1431
ports_media_busy=52
ports_media_quarantine=16
ports_wcs_agents_free=998
ports_wcs_agents_busy=0
ports_wcs_agents_quarantine=0
-----Stream Stats-----
streams_webrtc_in=1
streams_webrtc_out=51
И если активно нажимать "f5" на странице статистики, то можно увидеть как в течении теста количество "слушателей" то добавляется, то убавляется, хотя задержки запуска нового хрома расчитаны так, чтобы в конце первого "слушателя" было полное необходимое количество "слушателей".
 

Max

Administrator
Staff member
Посмотрите, пожалуйста, эту статью
Сравнение способов нагрузочного тестирования
По нашим тестам, мы упирались в производительность именно тестирующего сервера: Headless Chrome достаточно тяжелый даже для для сервера:
  • 2x Intel(R) Xeon(R) Silver 4214 CPU @ 2.20GHz (суммарно 24 ядра, 48 потоков);
  • 192GB RAM;
Попробуйте взять более мощный сервер в качестве тестирующего. Также попробуйте отслеживать метрики тестирующего сервера.
 

Max

Administrator
Staff member
Добрый день.
Мы воспроизвели поведение, которое Вы описали. Есть две проблемы:
1. Скрипт loadtest.sh не обрабатывает параметр maxsubscribers. Чтобы это обойти, необходимо в самом скрипте явно изменить значение переменной MAXSUBSCRIBERS на желаемое:
Code:
# Default values
MAXSUBSCRIBERS=100
2. При открытии страницы плеера в тесте по http вместо WebRTC используется MSE для проигрывания стрима. При этом количество соединений по websocket будет вдвое больше количества подписчиков на странице статистики, поскольку MSE использует два websocket соединения, одно для сигналинга и одно для передачи медиатрафика.
Мы скорректируем документацию и статью с учетом этих проблем.
 

saben

New Member
Добрый день.

1. Да, все настройки мы изначально правили непосредственно в скрипте;
2. Дело не в этом. Если бы была эта проблема, то количество wsc "соединений" было бы больше или равно количеству запущенных хромов. У нас ситуация обратная.

Попробовали сделать тестирование на парке машин, чтобы разделить нагрузку от атаки.
Итоговая мощность всех атакующих серверов: 84 ядра, 320G.
Провели тесты:
1. По 1 хрому на ядро - количество соединений на wsc (а также ports_media_busy) меньше чем количество запущенных хромов. Но утилизация ресурсов атакующих серверов не была выше 20-30%;
2. По 2 хрома на ядро - количество соединений на wsc (а также ports_media_busy) меньше чем количество запущенных хромов. Утилизация ресурсов атакующих серверов не была выше 40-45%;
3. По 3 хрома на ядро - - количество соединений на wsc (а также ports_media_busy) меньше чем количество запущенных хромов. Утилизация ресурсов атакующих серверов не была выше 70%.

По логам хромов и атакующих систем не было замечено "проблем" с совместным использованием ресурсов и убийством инстансов системами.

Но даже с учётом "потерянных" подписчиков удалось получить цифры близкие к 200 подписчиков, что вызвало резкий скачок утилизации CPU на атакуемой машине (8 ядер, 16G) до 70-80% на каждое ядро.
 

Max

Administrator
Staff member
По 1 хрому на ядро - количество соединений на wsc (а также ports_media_busy) меньше чем количество запущенных хромов
Эта проблема в наших тестах не воспроизводится. Как именно контролировали это значение? Рекомендуется настроить сбор метрик со страницы статистики в Prometheus+Grafana. Пример настройки сбора метрик приведен в статье 10 важных метрик WebRTC стриминга и настройка мониторинга Prometheus +Grafana.
Но даже с учётом "потерянных" подписчиков удалось получить цифры близкие к 200 подписчиков, что вызвало резкий скачок утилизации CPU на атакуемой машине (8 ядер, 16G) до 70-80% на каждое ядро.
В этом случае речь должна идти уже об оптимизации настроек WCS сервера. В статье Какой нужен сервер для 1000 WebRTC стримов?, в разделе "Подготовка к тестированию", приведены все основные твики настроек, которые позволяют поднять производительность WebRTC стриминга.
 

saben

New Member
Мониторинг настроен и бест-практис в конфигурации применены.
Скрины мониторинга очередного теста:
Количество хромов: 244.
На скрине видно как запускаются "все" подписчики, а потом резко исчезает некоторое количество.
 

Attachments

Max

Administrator
Staff member
На скрине видно как запускаются "все" подписчики, а потом резко исчезает некоторое количество.
Приведите, пожалуйста, скриншот метрики streams_webrtc_out во время этого теста
Также уточните характеристики публикуемого потока (разрешение/битрейт).
Кроме того, какую версию WCS тестируете? После 5.2.838 были фиксы по производительности, поэтому рекомендуем обновить WCS до последней сборки (5.2.1022 в настоящее время)
 

Max

Administrator
Staff member
По скриншоту, выглядит как три разных теста с разным количеством подписчиков, причем в течение одного теста количество не менялось.
Уточните также, как подсчитываются реально запущенные экземпляры Chrome?
Кроме того, на одном из скриншотов выше видны ненулевые очереди декодеров, это может означать, что включился транскодинг. Уточните, страница для теста открывается с указанием разрешения или без? Если указать разрешение, включится транскодинг видео, что даст дополнительную нагрузку на сервер.
 

saben

New Member
Да, тесты проводятся разные. Количество подписчиков не меняется это правда, но оно меньше количества запущенных подписчиков.
Экземпляры хрома подсчитываются достаточно просто:
1. Считается количество запущенных процессов хрома с "сетью" (/opt/google/chrome/chrome --type=utility --utility-sub-type=network.mojom.NetworkService);
2. Считается количество открытых соединений с "атакуемым хостом" (tcp 0 0 source ip:43136 dest ip:31318 ESTABLISHED 1924751/chrome0);
3. Выбирается минимальная сумма из перечисленных выше;
4. Суммируется по всем хостам.

Был создан простейший скрипт.
Bash:
#!/bin/bash

PORTS=`netstat -pt | grep 'flash phoner ip address' | grep "ESTABLISHED" | wc -l`
CHROME=`ps ax | grep NetworkService | grep -v "grep" | awk '{print $1}' | wc -l`

if [[ ${PORTS} < ${CHROME} ]]; then
  echo ${PORTS};
else
  echo ${CHROME};
fi;
В данном коде бывает что количество "хромов с сетью" больше, чем действительно открыто портов. Поэтому считается "фактически" открытые соединения между клиент-сервером. Т.к. кроме "хромов" на атакующих машинах никто больше обращается в атакуемый сервер, скрипт можно считать валидным.

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

Max

Administrator
Staff member
Да разрешение заведомо не указывается чтобы получать более "реальную картину".
Тогда непонятно, откуда берется декодинг. Обратите внимание во время теста на раздел статистики native_resources, там будет информация, из какого кодека и в какой транскодируется. Транскодинга во время нагрузочного теста необходимо избегать, т.е. публиковать H264+Opus и играть H264+Opus.
 

saben

New Member
Транскодинга во время нагрузочного теста необходимо избегать, т.е. публиковать H264+Opus и играть H264+Opus.
Почему? Звучит как "мы будем проводить нагрузочное тестирование, но создадим тепличные условия, которых никогда не будет в продуктивной среде".

Code:
native_resources=139762337640144,opus,9960960;139763467904176,opus,-121694;139761932415632,RESAMPLER:48000/48000,0
native_resources.audio_codecs=2
native_resources.audio_resamplers=1
native_resources.video_transcoders=0
native_resources.video_decoders=0
native_resources.video_encoders=0
native_resources.writers=0
В целом понятно. Причина такого поведения с количеством подписчиков не ясна и вряд-ли удастся получить ответ.
 

Max

Administrator
Staff member
Почему? Звучит как "мы будем проводить нагрузочное тестирование, но создадим тепличные условия, которых никогда не будет в продуктивной среде".
Конфигурация, которую Вы тестируете (8 vCPU, 16 Gb RAM, как упомянуто здесь), мало подходит для транскодинга видео. Напомним, что транскодинг двух 720p потоков занимает одно ядро vCPU. Если необходим транскодинг видео, нужно тестировать конфигурацию на столько ядер, сколько публикаций планируется, памяти желательно 64 Gb (32 Gb Java Heap).
native_resources=139762337640144,opus,9960960;139763467904176,opus,-121694;139761932415632,RESAMPLER:48000/48000,0
Транскодинг в приведенном Вами случае есть только по звуку, он дает значительно меньше нагрузки.
В целом понятно. Причина такого поведения с количеством подписчиков не ясна и вряд-ли удастся получить ответ.
Мы проводим свои тесты и пытаемся воспроизвести проблему. Пока выглядит так, что проблема на стороне headless Chrome.
200 подписчиков - хороший результат для тестируемой конфигурации, при условии, что применены следующие твики из упомянутых в рекомендованной ранее статье:
Аппаратное ускорение шифрования WebRTC трафика
Оптимизация доставки потока подписчикам
 

Max

Administrator
Staff member
Мы воспроизвели проблему на стороне Chrome. Найдено две причины, по которым headless Chrome стартовал в меньшем количестве экземпляров, чем задано:
1. Малое значение лимита клиентов Xorg сервера. Проблема решается добавлением в файл xorg.conf следующей секции настроек:
Code:
Section "ServerFlags"
    Option "MaxClients" "2048"
EndSection
2. Большие требования Chrome к числу открытых файлов в системе. Проблема решается увеличением лимита перед запуском скрипта loadtest.sh:
Code:
ulimit -n 1000000
Мы внесли изменения в документацию и обновили архив со скриптами.
 
Top