Ранее, анализируя возможности стандартных конфигураций серверов в Digital Ocean с точки зрения WebRTC стриминга, мы отмечали, что один сервер может обслужить до 2000 зрителей. В реальной жизни часто встречаются случаи, когда одного сервера недостаточно.
Допустим, любители азарта в Германии смотрят в реальном времени скачки в Австралии. Поскольку скачки — это не только конный спорт, но и большие выигрыши, при вовремя сделанных ставках, то видео должно быть доставлено с минимально возможными задержками.
Другой пример. Глобальная корпорация, один из лидеров рынка FCMG с филиалами в Европе, России и в Юго-Восточной Азии организует вебинары для обучения менеджеров по продажам с трансляцией из штаб-квартиры в Средиземноморье. Зрители должны видеть и слышать ведущего в реальном времени.
Эти примеры объединяют требования: доставить медиапотоки большому количество зрителей с низкой задержкой. Для этого потребуется развернуть сеть доставки контента — CDN.
Отметим, что классическая технология доставки потоков с использованием HLS не подходит, поскольку может давать задержки до 30 секунд, а это критично для шоу в реальном времени.
Представьте себе, что лошади уже пришли к финишу, результаты опубликованы на сайте, а болельщики еще досматривают забег. Этого недостатка лишена технология WebRTC, которая может обеспечивать задержки в переделах 1 секунды, при современных каналах связи это возможно даже между континентами.
Для начала посмотрим, как развернуть простейшую CDN для доставки WebRTC потоков, и как ее затем масштабировать.
Немного теории
Роли серверов в CDN
Сервер в CDN может выполнять одну из следующих ролей:
- Origin — сервер, предназначенный для публикации медиапотоков. Раздает потоки другим серверам, может раздавать и подписчикам.
- Transcoder — сервер, выделенный для транскодирования потоков. Забирает потоки с Origin серверов и раздает транскодированные потоки на Edge. С этой ролью мы разберемся в следующей части.
- Edge — сервер, предназначенный для раздачи потоков подписчикам. Забирает потоки с Origin или Transcoder серверов, не раздает потоки другим серверам CDN.
Технологии передачи медиапотоков
На Origin сервер можно публиковать WebRTC и RTMP потоки, либо захватывать потоки с других источников по RTMP, RTSP и другими возможными способами.
Подписчики могут играть потоки с Edge серверов по WebRTC, RTMP, RTSP, HLS.
Между серверами CDN желательно передавать потоки по WebRTC, для снижения задержки.
Статическая CDN
Статическая CDN полностью описывается на этапе конфигурирования. По сути, настройка статической CDN похожа на настройку балансировщика нагрузки: в настройках сервера-источника потоков перечисляются все приемники.
Например, у нас есть Origin сервер во Франкфурте, один Edge в Нью-Йорке и один в Сингапуре
В этом случае Origin настраивается примерно так:
<loadbalancer mode="roundrobin" stream_distribution="webrtc"> <node id="1"> <ip>edge1.thestaticcdn.com</ip> <wss>443</wss> </node> <node id="2"> <ip>edge2.thestaticcdn.com</ip> <wss>443</wss> </node> </loadbalancer>
Вот и первая проблема статической CDN: для того, чтобы добавить в такую CDN новый Edge сервер, или вывести сервер из CDN, требуется изменение настроек и перезапуск всех Origin серверов.
Потоки, опубликованные на Origin, транслируются на все перечисленные в настройках Edge серверы. Решение о том, к какому из Edge серверов подключится подписчик, также принимается на Origin сервере. Вот и вторая проблема: если зрителей нет или очень мало, например, в Сингапуре ранний вечер, а в Нью-Йорке глубокая ночь, потоки все равно транслируются на Edge 1. Трафик расходуется вхолостую, и совсем не бесплатно.
Эти две проблемы может решить
Динамическая CDN
Итак, мы хотим настраивать CDN без перезапуска всех Origin серверов, и не хотим передавать потоки на те Edge сервера, где нет подписчиков. В этом случае держать где-либо в настройках весь список серверов CDN не нужно. Каждый сервер должен сам формировать такой список, а для этого он должен в каждый момент времени знать актуальное состояние остальных серверов.
В идеале, в настройках должно быть достаточно указать точку входа, сервер, с которого начинается CDN. К этой точке входа каждый сервер при запуске должен отправить запрос и получить в ответ список узлов CDN и список опубликованных потоков. Если точка входа недоступна, сервер должен ожидать сообщений от других серверов.
Любые изменения своего состояния сервер должен рассылать другим серверам в CDN.
Простейшая CDN: в центре Европы
Итак, попробуем настроить и запустить динамическую CDN.
Допустим, для начала нам нужно раздать видеопотоки европейским зрителям, при этом необходимо поддерживать до 5000 пользователей. Предположим, что источник потоков находится также в Европе.
Разворачиваем три сервера в европейском дата-центре. В качестве элементов для сборки CDN будем использовать Flashphoner WebCallServer (WebRTC сервер потокового видео).
Настройка:
- Origin EU
cdn_enabled=true cdn_ip=o-eu1.flashponer.com cdn_nodes_resolve_ip=false cdn_role=origin
- Edge 1 EU
cdn_enabled=true cdn_ip=e-eu1.flashphoner.com cdn_point_of_entry=o-eu1.flashponer.com cdn_nodes_resolve_ip=false cdn_role=edge
- Edge 2 EU
cdn_enabled=true cdn_ip=e-eu2.flashphoner.com cdn_point_of_entry=o-eu1.flashponer.com cdn_nodes_resolve_ip=false cdn_role=edge
Обмен сообщениями между узлами динамической CDN происходит через Websocket, и, разумеется, Secure Websocket также поддерживается.
Внутри CDN потоки транслируются по WebRTC. В качестве транспорта, как правило, используется UDP, но можно переключиться на TCP, если нужно обеспечить качество трансляции при не очень хорошем канале между серверами. Увы, в этом случае задержки возрастают.
Перезапускаем серверы, открываем пример Two Way Streaming на сервере o-eu1, публикуем циклический ролик с таймером обратного отсчета от 10 минут до 0
Открываем пример Player на сервере e-eu1, играем поток
И делаем то же самое на e-eu2
CDN работает! Как можно видеть на скриншотах, время в ролике совпадает на публикующей стороне и у зрителей с точностью до секунды, спасибо WebRTC и хорошим каналам.
Далее везде: подключаем Америку
Теперь доставим потоки зрителям на американском континенте, не забудем и про публикацию.
Не выводя из работы европейскую часть CDN, разворачиваем три сервера в американском дата-центре
Настройка:
- Origin US
cdn_enabled=true cdn_ip=o-us1.flashponer.com cdn_point_of_entry=o-eu1.flashponer.com cdn_nodes_resolve_ip=false cdn_role=origin
- Edge 1 US
cdn_enabled=true cdn_ip=e-us1.flashphoner.com cdn_point_of_entry=o-eu1.flashponer.com cdn_nodes_resolve_ip=false cdn_role=edge
- Edge 2 US
cdn_enabled=true cdn_ip=e-us2.flashphoner.com cdn_point_of_entry=o-eu1.flashponer.com cdn_nodes_resolve_ip=false cdn_role=edge
Перезапускаем американские серверы, проверяем публикацию
и воспроизведение
При этом европейский сегмент продолжает работать. Проверим, увидят ли американские подписчики поток, опубликованный из Европы. Публикуем поток test_eu на сервере o-eu1
и играем его на e-us1
И это также работает! Что касается задержки, на скриншотах мы вновь наблюдаем совпадение таймера в ролике на публикующей стороне и у зрителей с точностью до секунды.
Обратите внимание, что играть непосредственно с Origin сервера потоки, опубликованные на другом Origin сервере, по умолчанию нельзя, но при особой необходимости, можно настроить и так
cdn_origin_to_origin_route_propagation=true
Продолжение следует
Итак, мы развернули простую CDN и затем успешно ее масштабировали на два континента, публикуя и играя WebRTC потоки с низкой задержкой. При этом мы не меняли параметры потоков при воспроизведении, что в реальной жизни требуется довольно часто: у всех зрителей разные каналы, и для сохранения качества трансляции приходится, например, снижать разрешение или битрейт. Этим мы займемся в следующей части…