一、千人会议的 QoS 挑战:从 10 人到 1000 人的质变
说实话,我第一次接到「千人会议」的需求时,心里是有点发怵的。做 WebRTC 的人都知道,10 个人的会议和 1000 个人的会议,根本不是一个物种。
10 个人的时候,每个人发一路视频,接收端也就 9 路。带宽不够?降分辨率、降帧率,甚至直接关掉几路,问题不大。但到了 1000 人,每个人发一路,接收端理论上要处理 999 路。你想想看,就算每路只有 500kbps,总带宽也接近 500Mbps。这还不算 CPU、内存、编解码的开销。
我在项目中遇到过最夸张的情况:一个 800 人的全员大会,某位领导的网络突然抖动,结果整个房间的接收端都开始卡顿。为什么?因为 SFU 没有做合理的带宽分配,一个用户的波动拖累了所有人。
所以,大规模场景下的 QoS,核心挑战就三个:
- 带宽瓶颈:上行、下行、服务器出口,处处是瓶颈
- 计算压力:编解码、转码、混流,CPU 和 GPU 扛不住
- 网络异构:有人用 5G,有人用 Wi-Fi,有人还在用 3G
说白了,你要在「有限的资源」和「无限的参与者」之间找到平衡点。
二、带宽分配策略:谁该吃蛋糕,谁该喝粥?
带宽分配,我个人的习惯是「按需分配,动态调整」。你不能给所有人一样的带宽,那是对资源的浪费。
2.1 基于活跃度的带宽分配
一个 1000 人的会议,真正在说话的可能只有 3-5 个人。其他人要么在听,要么在摸鱼。这时候,你应该把大部分带宽给活跃用户。
具体怎么做?
- 活跃用户:分配高清视频(720p/1080p),音频优先
- 非活跃用户:只传音频,或者传低分辨率视频(180p/360p)
- 静默用户:只传音频,甚至音频也可以降采样
我曾经在一个项目中,把非活跃用户的视频分辨率降到 180p,帧率降到 5fps。结果呢?服务器带宽直接降了 60%,用户感知几乎没有变化。因为没人会盯着一个不说话的人看。
2.2 基于网络质量的带宽分配
嗯,这里要注意:不是所有用户都有资格吃高清蛋糕。网络差的用户,你给他 1080p 他也收不到,反而会卡死。
我建议的做法是:
- 接收端定期上报网络状态(RTT、丢包率、可用带宽)
- SFU 根据上报数据,动态调整发送码率
- 如果丢包率超过 5%,自动降一档分辨率
- 如果 RTT 超过 300ms,降低帧率
说白了,就是「看人下菜碟」。网络好的吃高清,网络差的喝粥,但至少保证能喝上。
2.3 公平性 vs 效率
这里有个经典矛盾:公平性和效率怎么平衡?
如果完全公平,每个人分 1Mbps,那 1000 个人就需要 1Gbps 的服务器带宽。现实中不可能。如果完全效率优先,那网络差的人可能永远看不到视频。
我的经验是:保证底线,上不封顶。每个人至少保证音频流畅(约 50kbps),视频最低 180p(约 200kbps)。剩下的带宽,按活跃度和网络质量动态分配。
三、层级化 QoS 设计:从端到端的全链路保障
层级化 QoS,说白了就是把问题拆成三层:应用层、传输层、网络层。每一层解决不同的问题。
核心思想:不要试图在一个层面解决所有问题。应用层管策略,传输层管可靠性,网络层管优先级。
3.1 应用层 QoS
应用层离用户最近,也最灵活。我在这里主要做三件事:
- 码率自适应:根据网络状况动态调整编码参数
- 流优先级:音频 > 视频 > 屏幕共享 > 文件传输
- 丢包重传策略:关键帧(I帧)必须重传,非关键帧(P帧)可以跳过
举个例子:当网络拥塞时,我会优先保证音频的码率,然后压缩视频码率。如果还不够,就降低非活跃用户的视频分辨率。最后才考虑丢帧。
3.2 传输层 QoS
传输层主要靠 WebRTC 自带的机制:
- FEC(前向纠错):发送冗余包,允许一定比例的丢包恢复
- NACK(否定确认):接收端通知发送端重传丢失的包
- Jitter Buffer(抖动缓冲):平滑网络抖动,保证播放流畅
我记得有一次线上事故,某个区域的用户丢包率高达 20%。FEC 扛不住,NACK 也来不及。最后怎么解决的?我们把 FEC 的冗余度从 10% 提升到 30%,同时把 Jitter Buffer 从 100ms 增加到 300ms。虽然延迟变大了,但至少画面不卡了。
避坑指南:我曾经把 FEC 冗余度设得过高(50%),结果带宽消耗翻倍,反而加剧了拥塞。FEC 不是越高越好,要根据实际丢包率动态调整。
3.3 网络层 QoS
网络层是最底层的保障,也是最难控制的。因为你管不了用户的网络,只能管自己的服务器。
我常用的手段:
- DSCP 标记:给音频包打高优先级标记(EF),视频包打中优先级(AF),其他包打低优先级(BE)
- 带宽预留:在服务器出口预留 20% 的带宽给音频和关键信令
- 多路径传输:如果用户有多个网络接口(Wi-Fi + 4G),可以同时使用,提高可靠性
但说实话,DSCP 标记在公网上不一定生效,因为很多运营商会忽略它。所以,我更推荐在私有网络或专线中使用。
四、层级化 QoS 架构图
下面这张图是我自己总结的层级化 QoS 架构,你可以把它当作设计参考:
五、实战中的避坑指南
最后,分享几个我踩过的坑,希望能帮你少走弯路。
坑1:不要迷信 FEC
我曾经在一个项目中,把 FEC 冗余度设到 50%,以为能扛住 30% 的丢包。结果带宽翻倍,拥塞更严重,丢包率反而上升了。后来我改成动态 FEC:丢包率低时用 10%,丢包率高时用 30%,超过 30% 就放弃 FEC,改用 NACK + 降分辨率。
坑2:不要忽略音频优先级
有一次线上会议,视频卡得不行,但音频是好的。用户反馈说「虽然画面不动,但至少能听清」。这说明音频优先级策略生效了。反过来,如果音频也卡,那用户就彻底没法用了。所以,任何时候都要保证音频的带宽和优先级。
坑3:不要假设所有用户网络都很好
我见过最极端的案例:一个用户用 2G 网络参加 1080p 会议。结果他一个人占用了 SFU 的大量资源,还拖累了其他用户。后来我们加了一个「最低网络要求」的检测:如果带宽低于 500kbps,强制降为音频-only。虽然用户不爽,但至少不影响其他人。
六、总结
千人会议的 QoS,说白了就是「在有限的资源下,让尽可能多的人获得可用的体验」。没有银弹,只有权衡。
我个人的经验是:分层设计,动态调整,保证底线。应用层管策略,传输层管可靠性,网络层管优先级。三层协同,才能在大规模场景下稳住阵脚。
嗯,今天就聊到这里。如果你在实际项目中遇到什么问题,欢迎随时交流。