一、多源节点分发业务场景
不少中大型直播业务,会部署多套切片源站节点做高可用。一套推流同时分发至多台切片服务器,多台机器同时输出 HLS 直播 M3U8 和 TS 分片;CDN 多回源策略,随机向不同源节点回源拉取 M3U8 清单。
设计目标是实现源站高可用,某一台切片节点故障,CDN 自动切换到另外一台正常节点,直播不中断。但是很多业务上线之后,出现偶现播放异常:播放器一会跳回旧时间,一会向前跳跃,偶现解析报错。
根因:多台切片服务器系统时间、分片生成进度不完全一致,输出的 M3U8 清单 MEDIA‑SEQUENCE 序列号、分片列表不一样。CDN 一会回源节点 A,一会回源节点 B,hls.js 拿到两份内容不一致的 M3U8 清单,序列号跳变,播放器逻辑错乱,出现时间回退、花屏。
很多新手以为多台机器输出的 M3U8 天然会完全一样,忽略多节点之间同步一致性问题。调试多源节点带来的播放异常,我会使用 m3u8live.cn,分别加载不同源节点输出的 M3U8,对比 MEDIA‑SEQUENCE、分片条目差异。
二、多节点 M3U8 不一致典型故障现象
现象 1:直播播放时间偶现跳回过去几秒
CDN 回源在两台切片节点之间来回切换,两份 M3U8 的 MEDIA‑SEQUENCE 序列号差距较大,hls.js 拿到序列号更小的清单,播放时间回跳。
现象 2:偶现 FRAG_LOAD_ERROR 分片 404
节点 A 的 M3U8 记录某分片序列号,切换到节点 B 回源,节点 B 已经淘汰该旧分片,分片地址 404。
现象 3:偶现出现 #EXT‑X‑DISCONTINUITY 不连续标记,短暂花屏
两份节点 M3U8 分片序列对不上,hls.js 检测分片序号跳变,触发不连续逻辑,短暂花屏。
特点:故障偶现,单独访问任意一台源节点播放全部正常;只有 CDN 在多源之间切换回源的时候才复现,本地单节点测试很难复现。
三、产生不一致的核心原因
- 多台切片服务器系统 NTP 时间没有严格对齐,机器时间存在偏差,分片生成进度不一致。
- 多台 ffmpeg / 切片进程独立编码,内部时间戳、分片切割时刻存在微小差异,MEDIA‑SEQUENCE 起始序列号不一致。
- 各个节点 hls_list_size 配置虽然相同,但分片淘汰时机不完全同步,保留的分片条目数量不一样。
- CDN 回源策略随机轮询多源,没有做粘性回源,一次播放会话内来回切换不同源节点。
四、可行的解决方案
方案 1:CDN 开启会话粘性回源(优先推荐)
同一个用户播放会话,全程固定回源到同一台源节点,会话结束才切换。播放会话内不会跨节点拿到两份不一致 M3U8,规避跳变问题。节点故障的时候再做故障切换。
方案 2:所有切片节点严格 NTP 时间同步
所有源服务器开启 NTP 时间同步,机器时间偏差控制在几百毫秒以内,缩小分片生成进度的差异。但是不能完全消除 MEDIA‑SEQUENCE 序号差异,属于基础保障,不能单独解决全部问题。
方案 3:避免多台机器独立切片输出同一路直播
推流只输出到一台主切片节点;其它节点只做备份转发,不独立做 HLS 切片生成。所有 M3U8、TS 分片统一来自同一套切片输出。
方案 4:故障切换的时候,强制触发播放器重置
业务层感知源节点切换,通知播放器重置播放会话,重新加载 M3U8,处理分片序列跳变。
五、排查实操步骤
第一步,分别拿到各个切片源节点的直连 M3U8 地址,粘贴网页调试工具,对比 M3U8 原始文本,观察 MEDIA‑SEQUENCE 起始序列号、分片列表差异。 第二步,复现线上偶现跳变现象,确认故障发生时刻 CDN 回源切换了源站节点。 第三步,优先配置 CDN 会话粘性回源,同一会话固定源节点,故障才切换。
六、总结
直播多源切片高可用架构,如果 CDN 在播放会话内来回切换不同切片节点,不同节点输出的 M3U8 清单 MEDIA‑SEQUENCE、分片列表不一致,会造成播放时间回跳、分片 404、偶现花屏。单节点访问全部正常,问题只在跨节点切换回源时复现。优先使用 CDN 会话粘性回源,同一个播放会话固定源节点;所有源节点做好 NTP 时间同步。借助网页调试工具,对比多节点输出的 M3U8 清单,快速定位多源分发一致性问题。