SRS:如何用NGINX搭建HLS分发集群

SRS的集群,终于补齐了最后一块拼图,就是基于NGINX的HTTP文件分发集群,比如HLS分发集群。

并且,HLS分发集群,可以和HTTP-FLV一起工作。高并发,高扩展性的NGINX,YYDS。

边缘集群(Edge Cluster)就是为了解决很多人观看的问题,可以支持非常多的人观看直播流。注意:

  • SRS Edge只支持直播流协议,比如RTMP或HTTP-FLV等,参考RTMP Edge Cluster
  • SRS Edge不支持HLS或DASH等切片的直播流,本质上它们不是流,就是文件分发。
  • SRS Edge不支持WebRTC的流分发,这不是Edge设计的目标,WebRTC有自己的集群方式。

本文描述的就是HLS或DASH等切片的边缘集群,基于NGINX实现,所以也叫NGINX Edge Cluster。

NGINX Edge Cluster

NGINX边缘集群,本质上就是带有缓存的反向代理,也就是NGNIX Proxy with Cache。

+------------+          +------------+          +------------+          +------------+
+ FFmpeg/OBS +--RTMP-->-+ SRS Origin +--HLS-->--+ NGINX      +--HLS-->--+ Visitors   +
+------------+          +------------+          + Servers    +          +------------+
                                                +------------+          

只需要配置NGINX的缓存策略就可以,不需要额外插件,NGINX本身就支持:

http {
    # For Proxy Cache.
    proxy_cache_path  /tmp/nginx-cache levels=1:2 keys_zone=srs_cache:8m max_size=1000m inactive=600m;
    proxy_temp_path /tmp/nginx-cache/tmp; 

    server {
        listen       8081;
        # For Proxy Cache.
        proxy_cache_valid  404      10s;
        proxy_cache_lock on;
        proxy_cache_lock_age 300s;
        proxy_cache_lock_timeout 300s;
        proxy_cache_min_uses 1;

        location ~ /.+/.*\.(m3u8)$ {
            proxy_pass http://127.0.0.1:8080$request_uri;
            # For Proxy Cache.
            proxy_cache srs_cache;
            proxy_cache_key $scheme$proxy_host$uri$args;
            proxy_cache_valid  200 302  10s;
        }
        location ~ /.+/.*\.(ts)$ {
            proxy_pass http://127.0.0.1:8080$request_uri;
            # For Proxy Cache.
            proxy_cache srs_cache;
            proxy_cache_key $scheme$proxy_host$uri;
            proxy_cache_valid  200 302  60m;
        }
    }
}

Note: 可以配置缓存的目录proxy_cache_pathproxy_temp_path,改成能访问的目录就可以。

Note: 一般不要修改location配置,除非你知道代表什么含义,要改也先跑起来了再改。

一定不能只配置成纯Proxy,这样会把负载透传到SRS,系统支持的客户端数目,还是SRS支持的数目。

开启Cache后,无论NGINX多少负载,SRS都只有一个流。这样我们可以扩展多个NGINX,实现支持非常多的观看并发了。

比如1Mbps的HLS流,1000个客户端播放NGINX,那么NGINX的带宽就是1Gbps,而SRS只有1Mbps。

如果我们扩展10个NGINX,每个NGINX是10Gbps带宽,那么整个系统的带宽是100Gbps,能支持10万并发,SRS的带宽消耗只有10Mbps。

如何验证系统正常工作呢?这就要用到Benchmark了。

Benchmark

如何压测这个系统呢?可以用srs-bench,使用起来非常方便,可以用docker直接启动:

docker run --rm -it --network=host --name sb ossrs/srs:sb \
  ./objs/sb_hls_load -c 500 \
  -r http://your_server_public_ipv4/live/livestream.m3u8

而且也可以压测RTMP和HTTP-FLV:

docker run --rm -it --network=host --name sb ossrs/srs:sb \
  ./objs/sb_http_load -c 500 \
  -r http://your_server_public_ipv4/live/livestream.flv

Note: 每个SB模拟的客户端并发在500到1000个,具体以CPU不要超过80%为准,可以启动多个进程压测。

那就让我们动手搞个HLS集群出来吧。

Example

下面我们用docker来构建一个HLS的分发集群。

首先,启动SRS源站:

./objs/srs -c conf/hls.origin.conf

然后,启动NGINX源站:

nginx -c $(pwd)/conf/hls.edge.conf

最后,推流到源站:

ffmpeg -re -i doc/source.flv -c copy \
  -f flv rtmp://127.0.0.1/live/livestream

播放HLS:

启动压测,从NGINX取HLS:

docker run --rm -it --network=host --name sb ossrs/srs:sb \
  ./objs/sb_hls_load -c 500 \
  -r http://192.168.0.14:8081/live/livestream.m3u8

可是看到SRS的压力并不大,CPU消耗都在NGINX上。

NGINX边缘集群成功解决了HLS的分发问题,如果同时需要做低延迟直播,分发HTTP-FLV,怎么做呢?如果要支持HTTPS HLS,或者HTTPS-FLV呢?

NGINX完全没问题,下面就看如何配合SRS Edge Server,实现HTTP-FLV和HLS通过NGINX分发。

Work with SRS Edge Server

NGINX边缘集群,也可以和SRS Edge Server一起工作,可以实现HLS和HTTP-FLV的分发。

+------------+           +------------+
| SRS Origin +--RTMP-->--+ SRS Edge   +
+-----+------+           +----+-------+
      |                       |               +------------+
      |                       +---HTTP-FLV->--+   NGINX    +              +-----------+
      |                                       +   Edge     +--HLS/FLV-->--+ Visitors  +
      +-------HLS--->-------------------------+   Servers  +              +-----------+
                                              +------------+

实现起来很简单,只需要在NGINX的服务器上,部署一个SRS,并让NGINX工作在反向代理模式就可以。

# For SRS streaming, for example:
#   http://r.ossrs.net/live/livestream.flv
location ~ /.+/.*\.(flv)$ {
   proxy_pass http://127.0.0.1:8080$request_uri;
}

这样HLS由NGINX管理缓存和回源,而FLV则由SRS Edge缓存和回源。

这个架构虽好,实际上NGINX可以直接作为HLS源站,这样可以更高性能,是否可以呢?完全没问题,我们看如何完全用NGINX分发HLS。

NGINX Origin Server

由于HLS就是普通的文件,因此也可以直接使用NGINX作为HLS源站。

在超高并发的NGINX Edge集群中,也可以形成机房级别的小集群,从某个NGINX中集中回源,这样可以支持更高的并发。

使用NGINX分发HLS文件,其实很简单,只需要设置root就可以了:

  # For HLS delivery
  location ~ /.+/.*\.(m3u8)$ {
    root /usr/local/srs/objs/nginx/html;
    add_header Cache-Control "public, max-age=10";
  }
  location ~ /.+/.*\.(ts)$ {
    root /usr/local/srs/objs/nginx/html;
    add_header Cache-Control "public, max-age=86400";
  }

Note: 这里我们设置了m3u8的缓存时间是10秒,需要根据切片的大小调整。

Note: 由于目前SRS支持HLS variant,实现HLS的播放统计,因此没有NGINX这么高效,参考 #2995

Note: SRS应该要设置Cache-Control,因为切片的服务才能动态设置正确的缓存时间,减少延迟,参考 #2991

Debugging

如何判断缓存有没有生效呢?可以在NGINX日志中,加入一个字段upstream_cache_status,分析NGINX日志来判断缓存是否生效:

log_format  main  '$upstream_cache_status $remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
access_log  /var/log/nginx/access.log main;

第一个字段就是缓存状态,可以用下面的命令分析,比如只看TS文件的缓存情况:

cat /var/log/nginx/access.log | grep '.ts HTTP' \
  | awk '{print $1}' | sort | uniq -c | sort -r

可以看到哪些是HIT缓存了,就不会从SRS下载文件,而直接从NGINX获取文件了。

也可以直接在响应头加入这个字段,这样可以在浏览器中看每个请求,是否HIT了:

add_header X-Cache-Status $upstream_cache_status;

Note: 关于缓存生效时间,参考字段proxy_cache_valid的定义,实际上若源站指定了Cache-Control会覆盖这个配置。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容