Назад | Перейти на главную страницу

различное поведение в зависимости от имени файла и маршрутизации серверной части в NGINX

Уже несколько дней я ломаю голову над этой проблемой, но не могу найти "элегантного" решения. Я хотел бы использовать сервер NGINX в качестве источника потоковой передачи для некоторых каналов в реальном времени, которые будут распространяться через разные CDN.

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

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

upstream transcoder_pool_01 {
 server 192.168.1.1;
 server 192.168.1.2;
}

upstream transcoder_pool_02 {
 server 192.168.1.3;
 server 192.168.1.4;
}

map $livechannel $backend {
 channel1 transcoder_pool_01;
 channel2 transcoder_pool_02;
 channel3 transcoder_pool_03;
}

А до этого все нормально. Теперь наступает трудная часть.

Мой транскодер / упаковщики генерируют потоки по следующей схеме:

Главный манифест HLS: http://ip_address/liveapplication/channel_name/master.m3u8

Единые манифесты битрейта HLS http://ip_address/liveapplication/channel_name/channel_name-RESOLUTION/playlist.m3u8

Манифест DASH: http://ip_address/liveapplication/channel_name/manifest.m3u8

Сегменты: http://ip_address/liveapplication/channel_name/channel_name-RESOLUTION/chunk-xxxxxxx.ts (или chunk-xxxxxx.mp4, или chunk-xxxxxx.m4s)

Теперь по причинам, не зависящим от меня, CDN требует, чтобы DASH и HLS обрабатывались разными путями. И в дополнение к этому один и тот же исходный поток многократно используется повторно в разных средах и блоках каналов. По этой причине из CDN / Edges мой Origin получает такие запросы:

http://originserver/live-hls/environment-01/channel-block01/channel-name/master.m3u8

или

http://originserver/live-dash/environment-01/channel-block02/channel-name/manifest.mpd

или

http://originserver/live-dash/environment-02/channel-block01/channel-name/channel-name-SD/playlist.m3u8

или

http://originserver/live-dash/environment-02/channel-block01/channel-name/channel-name-SD/chunk-002314.m4s

и так далее....

На этом этапе, прежде чем пересылать запросы, мне нужно:

  1. изменить live-dash или live-hls на обычное liveapplication
  2. вырезать из URI среду и блок-канал
  3. оставшуюся часть передать как есть, но: 3a) установить очень длинный кеш для файлов с именем master.m3u8 и manifest.mpd, и для всех медиа-фрагментов 3b) установить очень короткий кеш для файлов с именем playlist.m3u8 (обратите внимание, что эти файлы находятся в том же подкаталоге, в котором находятся относительные чанки)

Я думал временно решить проблему, определив сервер, похожий на:

server {
 listen 80;
 server_name originserver;
 proxy_redirect off;
 proxy_http_version 1.1;
 proxy_read_timeout 10s;
 proxy_send_timeout 10s;
 proxy_connect_timeout 10s;
 proxy_ignore_headers Cache-Control;
 proxy_ignore_headers Set-Cookie;
 proxy_cache liveorigin_cache;
 proxy_cache_methods GET HEAD;
 proxy_cache_key $uri;
 proxy_cache_lock on;
 proxy_cache_lock_age 5s;
 proxy_cache_lock_timeout 1h;
 # cache valid for 5 seconds where not specified differently
 proxy_cache_valid 200 302 5s;
 proxy_cache_valid 404 1s;

location ~ /(live-hls|live-dash)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/(master.m3u8|manifest.mpd) {
     proxy_cache_valid 200 400s;
     add_header "X-MasterManifest-Tag" "true";
     proxy_pass http://$backend/liveapplication/$4/$5;
}

location ~ /(live-hls|live-dash)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/(.*)/playlist.m3u8 {
     proxy_cache_valid 200 2s;
     add_header "X-Playlist-Tag" "true";
     proxy_pass http://$backend/liveapplication/$4/$5/playlist.m3u8;
}

location ~ /(live-hls|live-dash)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/(.*)/(.*).(ts|mp4|fmp4|m4s) {
     proxy_cache_valid 200 2s;
     add_header "X-Segments-Tag" "true";
     proxy_pass http://$backend/liveapplication/$4/$5/$6/$7;
}

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

Но это точно не работает.

Я временно «исправил» проблему, заменив все местоположения одним местоположением, например:

       location ~ /(live-hls|live-dash)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/([a-z0-9_\.-]+)/(.*) {
                set $livechannel $4;
                add_header "X-General-Tag" "true";
                proxy_pass http://$backend/live/$4/$5;
       }

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

И я также считаю, что есть подход намного лучше, чем тот, который я думал использовать.

Может быть, используя вложенные локации? Я действительно заблудился.

Спасибо за вашу помощь. Alex