一条直播链路有五个角色,任何一段出问题都表现成「卡」。 延迟是六段加起来的,能调的只有一段。
前十三章一直在讲单点:协议、服务器、网页。这一章把它们串成一条线。 14.2 给一个完整系统的样子。
一、五个角色,各自只管一段
一条直播链路上有五个角色,它们的分工非常干净:
角色 干什么 失败时的现象
采集端 摄像头与麦克风出原始帧 没画面,或者一直黑 编码器 把原始帧压成码流 画面卡但音频正常,多半是 CPU 顶不住 推流端 把码流按协议送给服务器 一直重连,服务器看不到这条流 分发服务器 一份流复制给 N 个观众 有人能看有人不能,通常是带宽或连接数 播放端 解码并渲染 转圈、花屏、音画不同步
这五段是串行的,任何一段出问题都会表现成「直播卡」。
所以排障的第一步不是看日志,是先判断「卡在哪一段」: 推流端自己预览流畅、观众卡,问题在推流之后; 所有人都卡,问题在编码或推流;只有部分人卡,问题在分发或播放。
这个判断顺序很重要,因为五段的日志分散在五个地方。 不先缩小范围,就会一头扎进「服务器日志里看不出问题」的死循环。
二、延迟是六段加起来的
端到端延迟不是一个数,是六个环节的累加:
环节 典型耗时 为什么
采集 33 毫秒 30 帧一秒,每帧等 33 毫秒 编码 20 毫秒 硬件编码一段 40 毫秒的片子约 20 毫秒 推流缓冲 40 毫秒 至少凑满一个 GOP 才好切 服务器转发 5 毫秒 内存里拷一份,几乎不耗时 网络 30 毫秒 同城一个往返 播放器缓冲 300 毫秒 抗抖动的代价,可调 合计 428 毫秒 这就是「端到端延迟」
六段加起来大约 0.4 秒。 这里面只有最后一段是能随便调的,其余五段都是硬成本,想省只能换技术路线。
所以「把延迟从 3 秒降到 1 秒」的真实做法是: 先砍播放器缓冲(300 降到 100),再砍推流缓冲(40 降到 10), 剩下的采集与编码几乎动不了——那是物理下限。
注意这 0.4 秒是「理想值」。 教材里那个 3 秒的数字,通常是 HLS 路线——它还得再加一个切片的等待。 同一个系统,换协议就能差一个数量级,这就是前面第五章与第十三章的区别。
三、带宽是观众的乘法
观众数一多,带宽不是线性增长,是乘法:
观众数 单机直出 边缘数 源站出口
100 200 Mbps 1 2 Mbps 1000 2.0 Gbps 10 20 Mbps 10000 20.0 Gbps 100 200 Mbps
一千人看 2 Mbps,单机直出就要 2 Gbps 出口——一台机器做不到。 所以才有「边缘」:源站只出 100 路,每个边缘再复制给一百人。 源站出口从 20.0 Gbps 降到 200 Mbps,省了两个数量级。
但边缘不是白来的: 每个边缘都是一台机器、一份带宽、一份运维。 所以「要不要上边缘」不是技术问题,是「观众在哪儿」的问题。 观众集中在一个城市,一个边缘就够;全国分散,就得按区域铺。
这也是为什么大厂自己做 CDN,小厂买 CDN: 边缘的边际成本很低,但起步成本很高。 观众不到一定量级,自建边缘比买还贵。
四、三种架构,按规模选
规模不同,架构就不同,没有「最好的架构」这回事:
架构 适用规模 关键瓶颈
单机直出 几十人 网卡出口 源站加边缘 几千到几万 源站出口与边缘调度 多级加 P2P 十万以上 调度复杂度
教材这一章给的案例是第二种:源站加边缘。 这也是现实里最常见的一种,因为它刚好卡在「单机扛不住、又不需要自建 CDN」之间。
SRS 的集群配置(第 11.3 节)、Nginx 的多层反代(第十章),讲的都是这一种。 它们解决的是同一个问题:怎么让一份流,变成很多份,而源站只出一份。
第三种(多级加 P2P)在教材里没细讲,但它值得知道: 它的思路是让观众之间互相转发,进一步压低服务器带宽。 代价是调度极其复杂——谁给谁传、传多少、怎么防止作弊,每一项都是硬骨头。
五、动手 Demo:直播系统架构简介——一条链路上有五个角色
先把五个角色与它们失败时的现象列清楚。 再真算延迟预算与带宽阶梯,看瓶颈在哪一环。
STAGES = [("采集", 33), ("编码", 20), ("推流缓冲", 40),
("服务器转发", 5), ("网络", 30), ("播放器缓冲", 300)]
total = sum(ms for _n, ms in STAGES)
print("端到端延迟", total, "毫秒")
# 只有播放缓冲能调,看调到 100 能省多少
for cache in (300, 200, 100):
t = total - 300 + cache
print("播放缓冲", cache, "毫秒 -> 总计", t, "毫秒")
# 带宽阶梯:2 Mbps 一路,按一百人一个边缘算
kbps = 2000
for n in (100, 1000, 10000):
direct = n * kbps / 1000.0
edges = max(1, n // 100)
origin = edges * kbps / 1000.0
print(n, "人:直出", direct, "Mbps,边缘",
edges, "个,源站", origin, "Mbps")
实跑输出:
--------------------------------------------------------------------
直播系统架构简介——一条链路上有五个角色
--------------------------------------------------------------------
**① 五个角色,各自只管一段**
角色 干什么 失败时的现象
----------------------------------------------------------------------------------
采集端 摄像头与麦克风出原始帧 没画面,或者一直黑
编码器 把原始帧压成码流 画面卡但音频正常,多半是 CPU 顶不住
推流端 把码流按协议送给服务器 一直重连,服务器看不到这条流
分发服务器 一份流复制给 N 个观众 有人能看有人不能,通常是带宽或连接数
播放端 解码并渲染 转圈、花屏、音画不同步
**这五段是串行的,任何一段出问题都会表现成「直播卡」。**
**所以排障的第一步不是看日志,是先判断「卡在哪一段」:**
**推流端自己预览流畅、观众卡,问题在推流之后;**
**所有人都卡,问题在编码或推流;只有部分人卡,问题在分发或播放。**
**② 延迟是六段加起来的,不是某一处**
环节 典型耗时 为什么
--------------------------------------------------------------------
采集 33 毫秒 30 帧一秒,每帧等 33 毫秒
编码 20 毫秒 硬件编码一段 40 毫秒的片子约 20 毫秒
推流缓冲 40 毫秒 至少凑满一个 GOP 才好切
服务器转发 5 毫秒 内存里拷一份,几乎不耗时
网络 30 毫秒 同城一个往返
播放器缓冲 300 毫秒 抗抖动的代价,可调
合计 428 毫秒 这就是「端到端延迟」
**六段加起来大约 0.4 秒。**
**这里面只有最后一段(播放器缓冲)是能随便调的,**
**其余五段都是硬成本,想省只能换技术路线。**
**所以「把延迟从 3 秒降到 1 秒」的真实做法是:**
**先砍播放器缓冲(300 降到 100),再砍推流缓冲(40 降到 10),**
**剩下的采集与编码几乎动不了——那是物理下限。**
**想再往下,只能换 WebRTC,把分发与网络这两段一起重做。**
**③ 带宽是观众数的乘法,不是加法**
观众数 单机直出 边缘数 源站出口
------------------------------------------------
100 200 Mbps 1 2 Mbps
1000 2.0 Gbps 10 20 Mbps
10000 20.0 Gbps 100 200 Mbps
**一千人看 2 Mbps,单机直出就要 2 Gbps 出口——一台机器做不到。**
**所以才有「边缘」:源站只出 100 路,每个边缘再复制给一百人。**
**源站出口从 20.0 Gbps 降到 200 Mbps,省了两个数量级。**
**但边缘不是白来的:**
**每个边缘都是一台机器、一份带宽、一份运维。**
**所以「要不要上边缘」不是技术问题,是「观众在哪儿」的问题。**
**观众集中在一个城市,一个边缘就够;全国分散,就得按区域铺。**
**④ 三种架构,按规模选**
架构 适用规模 关键瓶颈
----------------------------------------------------
单机直出 几十人 网卡出口
源站加边缘 几千到几万 源站出口与边缘调度
多级加 P2P 十万以上 调度复杂度
**教材这一章给的案例是第二种:源站加边缘。**
**这也是现实里最常见的一种,因为它刚好卡在「单机扛不住、又不需要自建 CDN」之间。**
**SRS 的集群配置、Nginx 的多层反代,讲的都是这一种。**
六段加起来 428 毫秒,也就是 0.4 秒。 把播放缓冲从 300 降到 100,总计掉到 228 毫秒——省了一半还多。 而其余五段一共才 128 毫秒,再怎么优化也就省几十毫秒。 这就是「优化延迟」在实操上总是先动播放器参数的原因。 带宽那张表更直接:一万人直出要 20 Gbps,上边缘只出 200 Mbps。 两个数量级的差距,全靠「一份变一百份」这件事发生在边缘而不是源站。
30 秒实验
- 把 GOP 从 25 帧改成 50 帧,猜推流缓冲怎么变——变长,因为要凑满更久才切一片;延迟上升,码率下降。
- 把播放缓冲降到 0,猜画面会怎样——延迟最低,但网络一抖就卡住,因为没有任何余量。
- 一万人不上边缘直接连源站,猜先坏哪——网卡先满,然后所有人都卡,包括原本正常的那些人。
常见误区
- 「延迟就是推流那一下」——它是六段累加,每段都占一份。
- 「观众多了加机器就行」——带宽是乘法,加机器不解决出口。
- 「架构越先进越好」——几十个人用边缘,运维成本反而更高。
自测三问(点开对答案)
1. 端到端延迟里,哪一段最有调整空间? —— **播放器缓冲**,它就是为了抗抖动而故意加的。 2. 为什么一千人看 2 Mbps 就要 2 Gbps 出口? —— **服务器要给每个人各发一份**,不是发一份广播出去。 3. 边缘分发省的是哪一段带宽? —— **源站出口**,一份流只出到边缘,边缘再复制给观众。- ☐ (本节完,下一节 14.2.1 完整的流媒体服务器系统)