Эта статья продолжает цикл статей по нагрузочным тестам. Сегодня мы разберем методику тестирования и ответим на вопрос "Сколько IP камер можно подключить к WebRTC серверу?"
Зачем подключать IP камеры к серверу? Например, для того, что бы сделать простую систему видеонаблюдения, которая транслирует происходящее перед камерами на сайт. Из всего многообразия IP камер нас интересуют те экземпляры, которые отдают видеопотоки по протоколу RTSP. Дело в том, что браузеры не умеют играть RTSP потоки напрямую, поэтому, чтобы добавить видео с IP камеры на свой сайт нужно превратить RTSP видеопоток от IP камеры в WebRTC. И если с программной реализацией все более-менее понятно из статьи, то на этапе внедрения решения обязательно появится вопрос:
"Какой нам нужен сервер и сколько камер мы сможем к нему подключить?"
Приступим.
План тестирования
Опубликовать VOD поток на сервере WCS#1;
С помощью скрипта, использующего REST запросы, опубликовать RTSP потоки на сервере WCS#2;
Выбрать случайный RTSP стрим на WCS#2 и визуально оценить качество потока;
Оценить нагрузку на сервер WCS#2 по значениям метрик, собираемых системой мониторинга Prometheus для сервера WCS#2.
Тестирование будем считать успешным, если удастся подключить 1000 IP камер и не будет зафиксировано деградации потоков в результатах мониторинга или визуально.
Тестовый стенд
Для тестирования нам понадобятся
два WCS-сервера;
скрипт для проведения теста;
Предполагаем, что у вас уже есть установленные и настроенные серверы WCS. Если нет, то устанавливаем по этой инструкции, делаем твики для производительности и подключаем к мониторингу.
Для тестирования мы использовали два сервера:
WCS#1 (тестирующий) с характеристиками:
24 ядра, 48 потоков;
128 Gb RAM;
WCS 5.2.958;
OpenJDK version 14.0.1
и
WCS#2 (тестируемый) с характеристиками:
12 ядер, 24 потока;
96 Gb RAM;
WCS 5.2.958;
OpenJDK version 14.0.1
Настройки серверов
Файл flashphoner.properties (без настроек по умолчанию):
#webrtc ports range
media_port_from = 20001
media_port_to = 40000
#websocket ports
ws.port=8080
wss.port=8443
rtsp_activity_timer_timeout=86400000
wcs_agent_port_from=44001
wcs_agent_port_to=55000
global_bandwidth_check_enabled=true
zgc_log_parser_enable=true
zgc_log_time_format=yyyy-MM-dd'T'HH:mm:ss.SSSZ
rtsp_port_from=55001
rtsp_port_to=65000
Здесь мы увеличили диапазон портов для WebRTC, RTSP и WCS агента. Увеличили таймаут для RTSP потоков без подписчиков, а также указали настройки для сбора дополнительных метрик по загруженности сети и пауз в работе ZGC.
Для тестирующего сервера добавили дополнительные настройки для VOD — циклический захват потока и настройка продолжительности публикации VOD потока после отключения подписчиков:
vod_live_loop=true
vod_stream_timeout=14400000
Файл wcs-core.properties (без настроек по умолчанию):
-XX:ErrorFile=/usr/local/FlashphonerWebCallServer/logs/error%p.log
# ZGC
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xms24g -Xmx24g -XX:+UseLargePages -XX:ZPath=/hugepages
-Xlog:gc*:/usr/local/FlashphonerWebCallServer/logs/gc-core-:time
Здесь мы изменили настройки для именования файлов логов, включили использование ZGC, настроили размер Heap и включили использование страниц памяти.
Полные версии файлов настроек можно скачать в разделе «Полезные файлы» в нижней части статьи. Там же вы найдете панель для Grafana и файл скрипта для запуска тестирования.
Скрипт для тестирования
#! /bin/bash
camera=1000
curl -X POST -H 'Content-type: application/json' --data "{\"uri\":\"vod-live://bunny720p-test.mp4\", \"localStreamName\":\"test\"}" "http://localhost:8081/rest-api/vod/startup"
sleep 5s
for i in `seq 1 $camera`; do
curl --data "{\"uri\":\"rtsp://172.16.40.2:554/test?"$i"\",\"toStream\":\"RTSP-test-stream"$i"\"}" -X POST -H 'Content-type: application/json' -s http://172.16.40.3:8081/rest-api/rtsp/startup
sleep 0.1s
done
где:
camera — количество эмулируемых RTSP потоков.
В тестах мы будем использовать видеоролик с разрешением 720р. Подробнее параметры ролика на скриншоте ниже:
Тестирование
На тестирующем сервере WCS#1 запускаем скрипт для тестирования:
./RTSP-load-test.sh
Результат тестирования для 1000 захваченных RTSP потоков:
Тест был пройден успешно. По метрикам деградация стримов не была зафиксирована. Загрузка CPU по метрике Load average 1 не превысила 100 единиц.
Открываем на тестируемом сервере WCS#2 стандартный пример "Player" и запускам воспроизведение случайного RTSP потока из захваченных:
Контрольный поток воспроизводится с приемлемым качеством — без фризов, артефактов и снижения качества звука.
Мы провели еще несколько тестов
для 1500 RTSP потоков:
и для 2000 RTSP потоков:
По результатам этих тестов мы наблюдаем увеличение нагрузки на CPU и увеличение пауз в работе ZGC. По метрикам деградация стримов не фиксируется, но контрольный поток воспроизводится с заметными артефактами.
Как вы могли заметить, тесты не отличались большой продолжительностью. Поэтому принимать решение по выбору сервера для системы видеонаблюдения на их основе было бы не совсем правильно. Ведь в долгосрочной перспективе поведение системы может измениться.
Проведем еще один тест с тысячей захваченных RTSP потоков:
Этот тест продолжался без малого два часа. За это время можно увидеть, что критических изменений по загруженности ресурсов не наблюдается. Контрольный поток тоже все время воспроизводился корректно:
Хорошего стриминга!
Полезные файлы
Панель для Grafana:
Настройки WCS:
Скрипт для теста:
Ссылки
WCS на Amazon EC2 - Быстрое развертывание WCS на базе Amazon
WCS на DigitalOcean - Быстрое развертывание WCS на базе DigitalOcean
WCS в Docker - Запуск WCS как Docker контейнера
HTML5-трансляции с RTSP-IP камер - Функции сервера по воспроизведению RTSP видеопотоков
Документация по быстрому развертыванию и тестированию WCS сервера
Документация по мониторингу информации о нагрузке и ресурсах
Документация по организации мониторинга с помощью Prometheus
Описание файла настроек flashphoner.properties
Описание файла настроек wcs-core.properties
Документация по управлению памятью в Java