设计一个视频会议系统(WebRTC SFU)

本文系统设计一个视频会议系统:需求澄清与带宽估算、WebRTC 信令与 ICE 打洞、Mesh/SFU/MCU 三种拓扑对比、SFU 媒体转发与 Simulcast、拥塞控制与弱网对抗、录制与转码、房间与鉴权,并给出信令时序、拓扑对比表与容量权衡。

视频会议系统(Zoom、腾讯会议、Google Meet)是「实时音视频」里最综合的一类:它要在几百毫秒内把多方音视频互相送达,还要在丢包、抖动、带宽突降的网络里保持可听可看。核心矛盾是——多方通话的带宽随人数平方增长,如果让每个人给其他所有人各发一路流(Mesh),10 人会议每人要上传 9 路上行,家庭宽带根本扛不住。解决之道是引入中心转发节点(SFU),把「N×N」压成「N×1 + 1×N」。本文按照系统设计面试的标准答题结构,设计一个支持百人会议、弱网可用的视频会议系统。

一句话:视频会议的核心是「拓扑选择」——Mesh 适合 2~3 人,SFU 是多方会议的主流(只转发不解码),MCU 解码再混合适合极弱终端但服务器成本高。

一、需求澄清与量级估算

1.1 需求澄清

  • 会议规模:一对一、小组(<10)、团队(<100)、还是直播式大会(>1000)?
  • 交互方式:所有人双向互动,还是少数人讲、多数人看(更像直播)?
  • 媒体类型:纯音频,还是音视频 + 屏幕共享 + 录制 + 白板?
  • 终端:Web 浏览器、移动 App、桌面客户端、会议室硬件?
  • 网络条件:是否要求弱网(4G、跨国)可用?是否需要端到端加密?

明确假设(面向面试的合理假设):

需求项假设
规模常规会议 ≤100 人,大会用直播模式(仅少数上行)
媒体音视频 + 屏幕共享 + 云录制
拓扑SFU 转发为主
终端Web / iOS / Android / 桌面
网络支持弱网,端到端延迟目标 <400ms

1.2 量级估算

指标估算值推导
日活用户5000 万远程办公场景
峰值并发会议~50 万场工作日早高峰
峰值同时在线~500 万平均每场 10 人
单路上行码率1.5 Mbps720p 视频 + 音频
单路下行码率1 Mbps订阅多路时自适应
SFU 出口带宽~10 Gbps/节点每节点承载数百场会议

一句话:视频会议是带宽密集型系统,成本几乎全在「媒体服务器出口带宽」上;架构设计的核心就是让带宽花得值——该转发就转发,该降码率就降码率。

二、高层架构设计

   ┌────────┐   ┌────────┐   ┌────────┐   ┌────────┐
   │ 参会者A │   │ 参会者B │   │ 参会者C │   │ 参会者D │  (WebRTC 终端)
   └───┬────┘   └───┬────┘   └───┬────┘   └───┬────┘
       │ 信令(WS)    │             │            │ 媒体(SRTP/DTLS)
   ┌───▼────────────▼─────────────▼────────────▼───┐
   │               信令服务 (Signaling)               │
   │   房间管理 / SDP 交换 / ICE 候选交换 / 鉴权        │
   └───────────────────┬─────────────────────────────┘
                       │ 分配 SFU 节点
   ┌───────────────────▼─────────────────────────────┐
   │             媒体服务集群 (SFU 节点池)              │
   │  ┌──────────┐  ┌──────────┐  ┌──────────┐        │
   │  │ SFU-1    │  │ SFU-2    │  │ SFU-N    │        │
   │  │ 转发+Simulcast│ │        │  │          │        │
   │  └──────────┘  └──────────┘  └──────────┘        │
   └───────────────────┬─────────────────────────────┘
                       │
   ┌───────────────────▼─────────────────────────────┐
   │  录制/转码(媒体落对象存储) + TURN 中继 + 监控     │
   └─────────────────────────────────────────────────┘

四层职责:

  1. 信令服务:建立连接前交换 SDP 与 ICE 候选,管房间与鉴权。
  2. 媒体服务(SFU):接收上行流并转发给订阅者,是带宽与 CPU 的主要消耗点。
  3. 辅助设施:TURN 中继(NAT 穿透失败时兜底)、录制转码、监控。
  4. 存储:录制文件落对象存储。

2.1 信令与媒体的分离

  • 信令(Signaling):走 WebSocket,交换「我支持什么编解码(SDP)」和「我的网络地址(ICE candidate)」。信令可以可靠传输(TCP),因为只在连接建立和变更时用。
  • 媒体(Media):走 SRTP over UDP,必须低延迟、容忍丢包,不能走 TCP(丢包重传会造成卡顿放大)。
  • 职责:信令服务不碰媒体字节,媒体服务不碰信令,两者独立扩容。

一句话:把「协商怎么连」和「连上后传什么」分开——信令用可靠的 WebSocket,媒体用低延迟的 UDP,各自按自己的特性优化。

三、核心组件设计

3.1 三种拓扑对比

拓扑原理上行下行服务器成本适用
Mesh两两直连N-1 路N-1 路无2~3 人
SFU中心转发,不解码1 路N-1 路中(带宽)主流多方会议
MCU中心解码 + 混合1 路1 路高(CPU)极弱终端
  • Mesh:无服务器,延迟最低,但带宽 O(N²),仅适合一对一。
  • SFU(Selective Forwarding Unit):只转发不转码,服务端 CPU 极低,是 Zoom/Meet 的主流。难点在客户端要能处理多路解码。
  • MCU(Multipoint Control Unit):服务端把 N 路解码、混成 1 路再编码下发,客户端只收 1 路(省带宽),但服务端 CPU 爆炸(每场要解码 N 路 + 编码 1 路)。适合低端设备或超大混流。

一句话:SFU 用「带宽换 CPU」,MCU 用「CPU 换带宽」;现代会议系统几乎都用 SFU,MCU 只在特殊场景(低端机、纯转发到直播)保留。

3.2 WebRTC 连接建立(信令时序)

A               信令服务               B
│ 加入房间        │                    │
├───────────────▶│                    │
│◀── 房间成员列表 ─┤                    │
│ createOffer     │                    │
├── offer ───────▶│──── offer ────────▶│
│                │◀─── answer ────────┤
│◀── answer ──────┤                    │
│ 收集ICE候选      │                    │
├── candidate ───▶│──── candidate ────▶│  (双向交换,直到连通)
│                │                    │
│◀══════ SRTP/DTLS 媒体流(经 SFU 转发) ══════▶│

关键步骤:

  1. SDP 协商:交换编解码、分辨率、加密参数(offer/answer)。
  2. ICE 打洞:收集候选地址(主机/反射/中继),尝试直连;失败则走 TURN 中继。
  3. DTLS 握手:媒体加密密钥协商。
  4. 媒体传输:SRTP 加密的 RTP 流。

3.3 SFU 转发与 Simulcast

SFU 的核心能力是选择性转发:接收一路上行,转发给多个下行订阅者。为适配不同接收端带宽,上行用 Simulcast(同时发多档码率):

上行: 发送端同时推 3 档
   ┌── 720p @1.5Mbps ──┐
   ├── 360p @500kbps ──┤──▶ SFU
   └── 180p @150kbps ──┘
下行: SFU 按每个订阅者的带宽选档
   → 宽带用户收 720p
   → 弱网用户收 360p / 180p
   → 切档时只换转发层,无需重新协商(可用 SVC 或 Simulcast + 层切换)

Simulcast vs SVC:

方案原理优点缺点
Simulcast发送端独立编多路兼容性好、实现简单上行带宽 ×3
SVC分层编码,1 路含多层上行省带宽编码器复杂、支持少

3.4 拥塞控制与弱网对抗

实时音视频不能靠 TCP 重传,必须自建拥塞控制与抗丢包:

  • 带宽估计:用 GCC/REMB/TWCC 估计可用带宽,动态调码率。
  • 前向纠错(FEC):加冗余包,少量丢包直接恢复,不重传。
  • 重传(NACK/RTX):关键帧/关键包丢了请求重传(延迟敏感时慎用)。
  • 抖动缓冲(Jitter Buffer):吸收网络抖动,代价是增加延迟(通常 50~200ms)。
  • 音频优先:带宽不足时先保音频、降视频(音频不可用比视频卡更致命)。
  • 抗丢包编解码:Opus(音频)、AV1/VP9(视频)带错误隐藏。
可用带宽 2Mbps  → 发送 720p@1.5Mbps
可用带宽 600kbps → 降到 360p@500kbps
可用带宽 200kbps → 降到 180p@150kbps + 音频优先
丢包 5%         → 开 FEC + 抖动缓冲
丢包 20%        → 降码率 + 关视频只保音频

一句话:弱网对抗的本质是「主动降级」——宁可降清晰度也要保连续,靠带宽估计 + FEC + 抖动缓冲把「卡顿」换成「模糊」。

3.5 屏幕共享与录制

  • 屏幕共享:单独一条视频轨(内容编码),分辨率高但帧率低(如 1080p@5fps),与摄像头流分开订阅。
  • 录制:SFU 把各路上行流转发给录制节点,录制节点混流(可选)后落对象存储;或让各客户端本地录制再上传。混流录制省客户端资源但费服务器 CPU。
  • 转码/回放:录制文件转成通用格式(H.264/AAC MP4)供回放。

四、数据模型

存储用途说明
room房间元信息room_id、主题、最大人数、创建者
participant参会者user_id、room_id、角色、加入时间
sfu_nodeSFU 节点节点地址、负载、承载房间
recording录制任务room_id、文件地址、状态
signaling_session信令会话WebSocket 连接与房间映射

字段规范:room_id 用短 ID(如 9 位数字,方便口播);参会者角色分 host/cohost/attendee;房间状态 waiting/active/ended。

五、关键流程

5.1 加入会议

1. 客户端鉴权 → 信令服务申请加入 room
2. 信令服务分配/复用 SFU 节点(按 room 哈希 + 负载均衡)
3. 客户端与 SFU 建立 WebRTC 连接(SDP + ICE)
4. SFU 把该房间其他成员的上行流订阅给它(Simulcast 选档)
5. 客户端把上行流推给 SFU(Simulcast 3 档)

5.2 一进一出的媒体路径

A 上行(1 路 Simulcast) → SFU → 按 B/C/D 各自带宽选档 → 分别下发
                          │
                          └─ 同时一路 → 录制节点

要点:A 只上传 1 路(含 3 档),SFU 复制转发给 N 个订阅者,上行成本与人数无关,这正是 SFU 的关键优势。

5.3 弱网自适应

客户端检测丢包/延迟 → 上报 RTCP RR
SFU 收集反馈 → 调整下发给该客户端的档位
发送端带宽估计 → 调整上行码率

六、可靠性与一致性

6.1 媒体高可用

  • SFU 节点故障:会议迁移到备用节点,客户端重连(WebRTC 重协商),中断几秒。为减少影响,可按 room 做主备 SFU。
  • TURN 兜底:约 10~20% 的 NAT 组合打洞失败,必须部署 TURN 中继,否则这些用户完全连不上。
  • 跨地域:参会者分布广时,用多 SFU 级联(就近接入 + 节点间转发),降低跨国延迟。

6.2 一致性需求很低

视频会议不需要强一致:成员列表短暂不一致、某路视频晚到几百毫秒都无所谓。真正要一致的是房间成员加入/离开的事件顺序(避免幽灵成员),这靠信令服务的单房间串行化保证。

6.3 安全与隐私

  • 传输加密:DTLS-SRTP,媒体端到端加密;会议可开 E2EE(端到端加密),SFU 只转发密文(但 Simulcast 选档需要能看到帧头,E2EE 与 SFU 有取舍)。
  • 房间鉴权:进入房间需鉴权 + 可选密码/等候室,防止「会议轰炸」。
  • 信令防伪造:信令消息签名,防止伪造加入/踢人。

一句话:视频会议是「可用性优先、一致性次要」的系统——媒体丢几帧没关系,但连接绝不能断,所以重点投在 SFU 冗余、TURN 兜底和弱网自适应上。

七、性能与扩展

  • SFU 水平扩展:按 room 哈希分片到不同节点,节点无状态(状态在信令服务/Redis),可弹性扩缩。
  • 带宽优化:Simulcast 按订阅者带宽选档;大会模式只转发主讲人(+ 少量举手者),其余人只听。
  • 就近接入:多地部署边缘 SFU,参会者连最近节点,节点间用专线级联。
  • CPU 优化:SFU 只转发不转码,CPU 极低(主要是加密与转发);若要混流录制才吃 CPU。
  • 大房间策略:超过阈值的房间切「直播模式」——少数人上行,多数人下行(类似 设计一个直播系统 的 CDN 分发)。

容量与热点

  • 单 SFU 节点出口带宽 10Gbps,720p@1Mbps 可支撑约 1 万路下行;按 100 人会议每人订阅 10 路算,单节点可承载约 10 场百人会议。
  • 热点大课(万人):走直播/CDN 架构,不进 SFU 实时转发。

八、权衡与备选

决策点本文选型备选权衡说明
拓扑SFUMesh / MCUSFU 平衡带宽与 CPU;Mesh 限小会,MCU 适合低端终端
上行编码SimulcastSVCSimulcast 兼容好但上行 ×3;SVC 省上行但支持少
传输UDP(SRTP)TCPUDP 低延迟容忍丢包;TCP 重传放大卡顿
录制服务端 SFU 录制客户端本地录制服务端统一可靠;客户端省服务器但依赖终端
加密DTLS-SRTPE2EE普通加密兼容 SFU;E2EE 更强但与 SFU 选档冲突

关键取舍

  • 延迟 vs 质量:抖动缓冲越大越流畅但延迟越高;会议要交互,缓冲控制在 100ms 内。
  • 带宽 vs CPU:SFU 省 CPU 费带宽,MCU 反之;按部署成本选。
  • 功能 vs 兼容:Simulcast/SVC/E2EE 都有终端支持度问题,需按目标终端降级。

九、扩展场景与面试追问

9.1 与直播打通

「会议 + 直播」是常见需求:会议内 SFU 转发,对外直播时把混流推到 CDN。这条链路的转码与分发可参考 设计一个直播系统 与 WebRTC SFU/MCU 架构 的对比。会议内的聊天、举手、私聊等信令复用 设计一个即时通讯系统 的实时消息能力,低延迟分发可借鉴 WebRTC 低延迟直播 的传输优化。

9.2 云录制与 AI

  • 录制文件转码后落对象存储,供回放与下载。
  • 接 ASR 做实时字幕、会议纪要、说话人分离——这些是异步 AI 任务,与实时媒体链路解耦。

9.3 面试常见追问

追问关键回答
为什么用 SFU 不用 Mesh?Mesh 上行 O(N²),10 人就要传 9 路,家庭带宽扛不住
SFU 和 MCU 区别?SFU 只转发不解码(省 CPU 费带宽);MCU 解码混流(省带宽费 CPU)
弱网怎么保证不卡?带宽估计 + Simulcast 选档 + FEC + 抖动缓冲,主动降清晰度
打洞失败怎么办?TURN 中继兜底,约 10~20% 用户需要
上行带宽会随人数涨吗?不会,Simulcast 只上传 1 路(含多档),SFU 负责复制转发
大会议(万人)怎么做?切直播模式,少数人上行,多数人走 CDN 下行

十、总结

模块关键设计一句话记忆
拓扑SFU 转发上行 1 路,N×N 压成 N×1
信令WebSocket 交换 SDP/ICE信令可靠、媒体走 UDP
自适应Simulcast + 带宽估计按订阅者带宽选档
弱网FEC + 抖动缓冲 + 降级宁可模糊不可卡顿
高可用SFU 主备 + TURN 兜底媒体可丢、连接不能断
扩展就近接入 + 直播模式大房间走 CDN 不走 SFU

一句话:视频会议的面试核心是讲清楚「为什么用 SFU 而非 Mesh/MCU、信令与媒体为何分离、Simulcast 如何适配带宽、弱网怎么靠降级保连续」,把「上行成本与人数无关」和「连接不能断」这两条挂在嘴边,而不是只会说「用 WebRTC」。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「design」更多文章

  1. 设计一个 A/B 测试与实验平台
  2. 设计一个分布式锁服务
  3. 设计一个 LBS 附近的人系统(Geohash 与空间索引)