1.3 整体架构设计:直播、互动与回放三条线
概念弄清楚之后,我在白板上把整个平台画成了三条线:直播线负责音视频怎么传,互动线负责课堂消息怎么走,回放线负责课后视频怎么存、怎么发。这三条线各自独立、又在课堂这个场景里交汇。之所以一开始就分线设计,是因为它们的故障模式完全不同——直播卡了是音视频问题,聊天室刷屏是消息问题,回放看不了是存储分发问题。分开之后排错、扩容、压成本都能按线处理,互不拖累。
三条线各用什么产品
| 线路 | 涉及产品 | 数据流向 |
|---|---|---|
| 直播线 | TRTC | 老师推流 → TRTC 房间 → 学生拉流 |
| 互动线 | IM | 聊天、举手、系统通知在课堂群里广播 |
| 回放线 | COS 与 CDN | 云端录制入 COS → CDN 分发 → 学生点播 |
| 质量监控 | 云监控 | 三条线的指标统一采集、统一告警 |
| 业务服务 | 云服务器 | 排课、鉴权、课堂状态管理,串起三条线 |
直播线是主干,互动线贴着直播线跑,回放线在课后才真正发力。业务服务器是三条线的交汇点:开课时由它创建房间和课堂群,下课时由它触发录制文件处理。这套结构在后面迭代了一年多,始终没做过伤筋动骨的改动。
三条线的产品选择也不是拍脑袋定的。互动线选 IM 而不是自己在 WebSocket 上撸一套聊天,一来群组、消息漫游、离线推送这些能力 IM 已经备好,二来 3.2 节要讲的举手连麦信令完全可以复用消息通道,不用额外维护一条长连接。回放线用 COS 加 CDN 的组合,则是看中存储和分发的解耦:源文件在 COS 里安安静静存着,分发速度交给 CDN,两边可以各自优化、各自计费。
一堂课的完整链路
光看产品拼图还是抽象,我把一堂课从头到尾的时序拆开列在下面。这张表后来成了我和机构老师对需求时的通用语言,谁在哪个环节出问题,顺着表一指就清楚。
| 步骤 | 动作 | 涉及线路 |
|---|---|---|
| 1 | 学生打开课堂页面,业务服务校验身份与上课时间 | 业务服务 |
| 2 | 学生进 TRTC 房间,拉老师的老师画面与声音 | 直播线 |
| 3 | 学生在 IM 课堂群发消息、抢答、提问 | 互动线 |
| 4 | 学生举手,老师同意后学生上麦推流 | 直播线加互动线 |
| 5 | 下课后,云端录制文件落入 COS 存储桶 | 回放线 |
| 6 | 回放页从 CDN 拉取视频,学生按目录复习 | 回放线 |
第 4 步是最能体现两条线配合的环节:举手本身是 IM 消息,上麦本质是 TRTC 角色切换,老师在同意的那一刻由业务服务通知两端同时动作,任何一端慢了半拍,学生就会看到“已经被叫起来但画面没出来”的尴尬场面。
这张时序表后来还被我用作了验收清单:每接一个新功能,先看它在链路上落在哪一步,会不会把前后步骤的接口改坏。比如后期加“随堂测验”,它的位置在第 3 步和第 5 步之间,挂在互动线上,和直播线完全解耦——学生在等题目的时候,老师的讲课画面是一秒都不能卡的。
各模块职责划分
三条线确定之后,我把每个模块的职责也固定了下来,避免开发时互相推诿。这张表建议在团队里过一遍再开工,能省掉大量扯皮的时间。
| 模块 | 职责 | 不做什么 |
|---|---|---|
| TRTC 房间 | 音视频传输与连麦调度 | 不管聊天内容 |
| IM 课堂群 | 聊天、举手、公告等消息广播 | 不传音视频 |
| 云端录制 | 把房间音视频录成文件 | 不管文件存储与分发 |
| COS 存储桶 | 录制文件落地、生命周期管理 | 不做播放加速 |
| CDN | 回放加速与防盗链 | 不存源文件 |
| 云监控 | 全链路指标采集与告警 | 不参与业务逻辑 |
边界清晰之后,每个模块的选型、压测、成本优化都能单独推进。比如后来回放流量上涨,我只需要调 CDN 的缓存策略,完全不用动直播线的代码,这就是分线设计带来的好处。
“不做什么”这一列列出来的时候,团队里还讨论过录制归谁。云端录制本身只在上课时工作,产物是文件;文件落进 COS 之后怎么管、谁在管,就是存储层的事。这条边界让 4.2 节的生命周期管理可以完全独立演进,不用拉着音视频模块一起改。
部署拓扑:哪些东西放哪里
架构图落在部署上其实很轻:一台云服务器跑业务服务,承载排课、鉴权、课堂状态管理;TRTC 房间和 IM 课堂群都在云服务的后端,我们只管调用;COS 存储桶开了几个,按课程体系分目录;CDN 接上回放域名;云监控盯住前面所有东西。整个平台我们自己维护的机器只有那一台业务服务器,其余全是云服务,这对小团队的意义不用多讲。
部署拓扑还有一个设计原则:无状态的部分尽量托管,有状态的部分握在手里。课堂的排期、学生名单、权限这些业务数据放业务服务自己的数据库;音视频流转给云服务;视频文件托管给 COS。真要迁移或扩容的时候,要动的只有业务服务那一层。
容灾与降级的初步考虑
三条线架构另一个好处是天然支持降级。直播线挂了,互动线还在,老师可以先用语音加文字把课上完;互动线挂了,直播线还在,大不了临时用外部群沟通;回放线是课后的事,和上课完全错开,完全不影响课堂进行。弱依赖的模块之间互相兜底,整个平台的可用性比把鸡蛋放一个篮子里高得多。云监控负责在第一时间告诉我哪条线在报警,这部分的实战配置我放在 5.2 节展开。
顺带说明,三条线的思路对排课也有影响。系统排课时会把一节课的三条线一起初始化:创建 TRTC 房间、创建 IM 课堂群、预约录制任务。三件事在一个事务里完成,任何一件失败就整节课回滚,避免出现“有房间没聊天室”这种半拉子状态。课堂结束后也是统一下课:解散群、销毁房间、确认录制文件落盘。一致性这根弦从设计第一天就要绷紧,不然线上数据会越积越乱。
这份架构最后还通过了机构负责人的一次“灵魂拷问”:如果明天学生数量翻三倍,系统撑得住吗?答案是三条线的扩容方式各不相同:直播线和互动线是云服务,弹性由厂商保障,我们要做的只是提前确认套餐余量;回放线靠 CDN 缓存,翻三倍流量也主要是缓存命中率的问题;真正需要评估的只有业务服务器那一台。架构拆清之后,“撑不撑得住”这个问题从玄学变成了可以逐项回答的清单,这也是我喜欢这套设计的原因。
一句话版本
整套架构压缩成一句话,就是:老师推流到 TRTC 房间,聊天和举手走 IM 课堂群,房间录制成文件后落入 COS,学生课后经 CDN 点播回放,云监控全程盯梢。这句话挂在我们团队协作区的墙上,新来的兼职开发看一眼就知道平台怎么转。
再展开半句:所有跨线的协调动作(开课、下课、上麦同意、录制回滚)都由业务服务器发起,它是唯一有“全局视角”的角色。为什么不让客户端直接相互通信?因为客户端的网络环境千差万别,让一个可靠的中心节点做裁判,比让三十个终端互相协商稳定得多。这也是为什么业务服务器虽小,却是整套架构里最不能掉链子的一环。
这套架构也不是没有代价。代价是业务服务器的实现复杂度集中:它要对三条线做协调,任何一条线的接口变动都会牵动它。所以我把业务服务的接口按线分了包,每条线的协调逻辑互不混杂。这算不上优雅,但对十人团队刚刚好——维护复杂度可控,排错时跟着线走就能定位到问题模块。
架构设计小结
| 设计决策 | 理由 |
|---|---|
| 三线分离 | 故障隔离,各自扩容 |
| 业务服务器统一协调 | 客户端环境复杂,中心裁判更稳 |
| 课堂状态一次性初始化 | 避免半拉子状态污染数据 |
| 录制与存储解耦 | 分发优化不影响课堂 |
架构想清楚之后,后面几篇就是逐线填代码。下一节先解决最现实的问题:这套架构每个月要花多少钱,以及怎么把预算控制在机构能接受的范围内。
本篇从选型到概念、从架构到成本,形成了一个完整的决策闭环。从下一篇开始,我们进入真正的代码实战,先从 TRTC 房间的接入讲起。
为什么三条线要分开设计
分线设计还有一个考虑:三条线的资源消耗节奏完全不同。直播线随上课时间走,一小时课消耗一小时时长;互动线随在线人数走,消息量与并发挂钩;回放线的流量则在课后集中爆发,而且可以慢慢优化。如果揉成一团,一条线的波动一定会连累另外两条。比如开学季回放流量猛增时,因为回放走的是 CDN,直播课堂数据完全不受影响。三线分离的本质是“把不稳定隔离在各自的桶里”,这个原则在我后来做扩容和成本复盘时反复被验证是对的。
再往前想一步,分线还方便定责任。出故障的时候第一句话永远是“哪条线挂了”,而不是“谁的代码挂了”。监控大盘按线分屏,告警按线分组,值班表自然也按线排。对一个兼职运维的团队,这种清晰度比任何花哨的架构图都实用。
架构图有了,下一节就要面对最现实的问题:这样一套东西每个月要花多少钱。如果你对云产品计费方式还不太熟悉,可以先翻翻 《腾讯云实战清单》 里的计费章节;对监控指标体系感兴趣的,《数据看板实战》 可以为第 5 篇的质量监控打打基础;想扩展自动化运维能力的,也可以提前了解 《1Panel 面板常见问题》 中的服务器管理技巧。
延伸阅读
- 《腾讯云实战清单》:各产品计费方式与组合建议
- 《数据看板实战》:质量监控指标的可视化呈现
- 《1Panel 面板常见问题》:小团队服务器面板管理
