1) 【一句话结论】
针对百万级用户在线教育直播系统,采用微服务拆分架构,核心通过WebRTC分布式SFU实现低延迟流传输,结合消息队列解耦互动服务,利用缓存+分布式存储处理高并发,并部署多活数据中心配合半同步复制与OSS跨区域复制,保障高并发、容灾与性能。
2) 【原理/概念讲解】
老师口吻:高并发直播系统需解决流传输、互动、存储、容灾四大问题,以下是关键组件设计:
- 直播流传输:采用WebRTC的分布式SFU(Selective Forwarding Unit,即“流中央调度站”),将百万用户流转发到边缘节点。部署多区域SFU集群(如华北、华南、华东),通过全局负载均衡(如Consul+Nginx)实现用户流就近转发,减少跨区域延迟。结合动态码率调整(H.264 VBR)根据网络状况优化码率,用抖动缓冲区(Jitter Buffer)平滑输出,同时控制延迟。
- 互动服务:消息队列(如Kafka)解耦弹幕、问答等逻辑,避免实时请求阻塞主流程。生产者配置16KB批量发送(减少网络开销),ACK=1(最小延迟,业务可容忍ms级延迟),重试策略(指数退避)保障消息可靠。
- 缓存与存储:Redis缓存热门课程信息、用户状态(热点数据预热,如访问频率高的课程提前加载到缓存);击穿用Redis分布式锁(
SETNX key expire-time value加锁,设置10秒过期时间防死锁),雪崩用随机过期时间或热点数据预热。回放文件存储在OSS,通过CDN加速播放。
- 容灾:多活数据中心,数据通过MySQL半同步复制(延迟优化至1秒内,业务可容忍)和OSS跨区域复制,故障时通过负载均衡快速切换(30秒内),保障99.9%可用性。
3) 【对比与适用场景】
| 技术方案 | 定义 | 特性 | 使用场景 | 注意点 |
|---|
| WebRTC SFU(集中式) | 单个SFU服务器转发所有用户流 | 流转发效率高,但单点压力大 | 百万级用户直播(延迟敏感) | 需高可用部署,避免单点故障 |
| WebRTC SFU(分布式) | 多个SFU节点,用户流就近转发 | 负载均衡,减少单点压力 | 更大规模(跨区域),百万+用户 | 需全局负载均衡,状态同步复杂 |
| 消息队列(Kafka vs RabbitMQ) | 异步通信中间件 | Kafka:延迟低(ms级)、吞吐量高;RabbitMQ:延迟中 | 实时解耦(弹幕、问答),事务场景 | Kafka需配置批量发送、ACK机制;RabbitMQ需事务支持 |
| MySQL复制(主从 vs 半同步) | 数据库数据同步 | 主从:异步复制,延迟1-2秒;半同步:主库写完成前至少1个从库确认 | 业务对数据实时性要求不高(如回放数据) | 半同步复制提升一致性,但增加延迟 |
| 多终端同步(同步 vs 异步) | 更新用户状态方式 | 同步:直接数据库更新(性能低);异步:消息队列同步状态(减少数据库压力) | 多终端(PC/手机)状态同步 | 异步同步需保证状态一致性,切换延迟低 |
4) 【示例】
用户加入直播流程伪代码(最小可运行示例):
用户请求加入直播:
1. Nginx负载均衡分发请求到直播流服务实例。
2. 直播流服务检查用户权限(Redis缓存权限,热点数据预热)。
3. 调用WebRTC API,建立与SFU服务器的连接(用户设备作为端点,SFU作为中转)。
4. 直播流服务将用户加入房间,并发布用户加入事件(通过Kafka)。
5. 其他用户收到事件,更新本地用户列表(多终端同步)。
6. 返回成功响应,包含房间ID、连接参数(如ICE候选、SDP)。
5) 【面试口播版答案】(约90秒)
“面试官您好,针对百万级用户直播系统,我设计的架构核心是围绕WebRTC分布式SFU实现低延迟流传输,结合消息队列解耦互动,缓存+分布式存储处理高并发,容灾多活保障可用性。具体来说,直播流服务通过分布式SFU集群,用户流就近转发,动态码率调整和抖动缓冲区确保延迟;互动服务(弹幕、问答)通过Kafka异步处理,生产者配置16KB批量发送,ACK=1保障延迟;缓存Redis用SETNX加锁(10秒过期)防死锁,回放文件存OSS+CDN。容灾方面,多活数据中心用MySQL半同步复制(延迟1秒内),OSS跨区域复制,故障切换30秒内,满足99.9%可用性。整体架构通过拆分服务、异步处理、缓存和分布式存储,能支撑百万级用户同时在线,并处理高并发、容灾等挑战。”
6) 【追问清单】
- 问:分布式SFU如何处理百万用户流转发效率?比如跨区域延迟?
回答要点:部署多区域SFU节点(如华北、华南、华东),全局负载均衡(Consul+Nginx),用户流就近转发,减少跨区域延迟,结合动态码率调整优化带宽。
- 问:Kafka生产者批量大小和ACK级别如何影响延迟?比如16KB批量,ACK=1?
回答要点:批量发送减少网络开销,16KB批次可减少请求次数;ACK=1(最小延迟,业务可容忍ms级延迟),重试策略指数退避,确保消息可靠。
- 问:Redis分布式锁的过期时间设置,比如10秒,如何避免死锁?
回答要点:加锁时设置过期时间(如10秒),若业务处理超时,锁自动释放;加锁失败时等待锁释放或重试,避免死锁。
- 问:MySQL半同步复制如何优化主从延迟?比如1秒内?
回答要点:半同步复制(Semi-Synchronous Replication)确保主库写操作完成前至少有一个从库确认,减少延迟;结合增强型复制(如PXC),进一步降低延迟至1秒内,保障数据一致性。
- 问:多终端同步时,用户设备切换(如PC到手机),如何快速更新状态?
回答要点:用户服务统一管理连接状态,设备切换时通过Kafka发布状态变更事件,各服务(直播流、互动、回放)订阅事件,快速更新多终端数据,切换延迟控制在1-2秒内(网络良好时)。
7) 【常见坑/雷区】
- 坑1:直播流传输只说WebRTC,未提分布式SFU部署策略,被问百万用户流转发效率时,无法解释如何处理。
雷区:回答时说“用WebRTC直接P2P”,被反问百万用户时,解释不了中转问题。
- 坑2:消息队列选择Kafka,但未说明延迟或可靠性参数,被问延迟时,无法解释如何保证。
雷区:说“Kafka延迟低”,被追问具体延迟值(如ms级),无法回答。
- 坑3:缓存击穿时,只说用锁,未说明锁的加锁策略(如过期时间),被问死锁时如何处理。
雷区:回答时说“用互斥锁”,被问锁超时怎么办,解释不了。
- 坑4:容灾方案只考虑主从复制,未说明故障切换时间,被问切换时间时,无法给出具体数值(如30秒内)。
雷区:说“故障时切换”,被追问时间,无法回答。
- 坑5:多终端同步用同步数据库,导致性能问题,被问性能时,解释不了如何优化(如异步同步)。