摄行科技 企业活动影像服务
直播弹幕限流怎么设计才扛得住万人同时刷屏-摄行科技
新闻资讯

直播弹幕限流怎么设计才扛得住万人同时刷屏

直播弹幕限流不该只堵在服务端入口。本文按水库四段拆开客户端节流、网关闸门、批量合并下发和渲染降级的具体阈值与实测数据,想扛住万人同时刷屏欢迎联系我们做方案。

直播弹幕限流怎么设计才扛得住万人同时刷屏-摄行科技

直播知识

直播弹幕限流怎么设计才扛得住万人同时刷屏

摄行科技

去年 12 月 4 号晚上八点零五分,华北一所高校南区礼堂的校友线上晚会,在线人数刚过一万一千二,弹幕通道直接白屏了四十多秒。那次事故之后我重写了整套直播弹幕限流的策略,思路是把弹幕系统当水库来管:上游进水、闸门、泄洪道、下游河道,四段各管各的水位。

这套东西不玄乎,但每一段的阈值都得靠实测抠出来,抄别人的数字大概率不合用。公开课的弹幕节奏跟发布会完全不是一回事,前者稀稀拉拉一整场没几条,后者能在三十秒里把一年的量刷完。

为什么直播弹幕限流要按水库四段来拆

弹幕流量的形态跟平常的接口请求完全不一样。它不是均匀的,是一波一波的浪。主讲人一句包袱抖响,三秒之内 QPS 能从 900 蹿到 3.8 万,然后二十秒内落回一千出头。你按平均值配的容量,遇上这种浪一冲就散。

水库这个类比好用,是因为它天然分了四段:客户端发送量是进水,网关是闸门,服务端往下推是泄洪道,浏览器渲染是下游河道。哪一段的水位管不住,整条链路都得涨。摄行科技这两年做的十几场万人级线上会议,都是照这个分段去排查的。

上游进水:客户端本地节流才是第一道闸

这里就是我要说的反常识那一条:限流不该限在服务端入口,得先在客户端做本地节流。

行业里的默认做法是服务端全量收下来再按规则丢。听着挺公平,实际上账算反了。一万人同时刷,每条弹幕带上用户 ID、房间号、时间戳、签名,一个包三百多字节,全量收下来光入口带宽就得 11.4 Mbps,还得占满长连接的读缓冲。收进来再丢,带宽和 CPU 早就烧完了,丢得再准也没意义。

我们现在的客户端策略是三条:单用户发送间隔硬锁 1.2 秒,本地队列超过 5 条直接吞掉最旧的,同一句话 10 秒内重复发直接静默成功。最后这条特别管用,刷屏的人有一半是在疯狂点重发按钮,本地假装发出去了,他就不点了。

这三条一上,实测上行流量掉了 62% 到 71%,服务端还没开始限流,浪已经削掉大半。

有人担心本地节流会不会把正经发言也拦掉。我们统计过那场晚会的原始日志,被本地策略拦下的一万四千多条里,重复内容占 78.6%,剩下的绝大多数是 0.4 秒内的连点。真正被误伤的不到两百条,比例低到可以接受。做直播弹幕限流最怕的就是为了那 1% 的边缘情况,把 99% 的成本全扛在服务端。

闸门:网关侧的令牌桶该开多大

到了网关这层,剩下的水才需要真正的闸门。我们用双层令牌桶:房间级和用户级。

房间级桶容量按在线人数动态算,经验公式是在线数除以 8,再加 200 作底。一万一千人的房间,桶容量 1575,每秒补充 1200 个令牌。用户级桶固定容量 3,每 1.5 秒补 1 个,防的是绕过客户端的脚本。

在线人数这个数字得准,桶容量全靠它算。这个数怎么统计其实挺有讲究,直播房间的并发人数是怎么统计出来的 里说得比较透,去重口径不一样,算出来能差三成。

超出令牌的弹幕怎么处理?我们不返回错误码,返回成功但不入库。这事儿听着有点不地道,可实测下来用户体验反而好:返回失败,客户端会重试,重试又是一波流量,越限越堵。

不过有两类消息永远不能被桶拦住:主持人和管理员发的公告,还有互动指令类的消息。我们给这两类单开一条快车道,不走令牌桶,只做一个每秒 30 条的硬上限兜底。摄行科技接过几场需要现场抽奖的会,抽奖口令要是被限流吞了,那才是真的收不了场。

泄洪道:把 4.3 万条压成每秒 18 帧下发

闸门放行之后的水,不能一条一条往下游倒。单条推送的开销主要在协议头和系统调用上,一万人在线、每秒 1200 条,逐条推就是每秒一千两百万次写操作,机器直接躺平。

我们的做法是按时间窗合并。55 毫秒开一个窗,窗内所有弹幕打成一个包,一次性广播出去,相当于每秒 18 帧的节奏。去年那场晚会全程收到 4.3 万条弹幕,合并之后实际下发包数只有 2.1 万个,出口带宽从峰值 340 Mbps 压到 96.7 Mbps。

包里的字段也得瘦身。用户昵称超过 6 个字截断,头像 URL 换成 CDN 短码,时间戳用相对秒数而不是完整字符串。这几刀砍下来单包体积从 1.4 KB 降到 480 字节左右。

合并这个动作是要吃 CPU 的,别忘了给它留算力。转码和消息合并抢核心的时候谁都跑不快,直播转码集群的成本是怎么被算力吃掉的 里那笔账我建议做架构的都看一遍。

下游河道:客户端渲染是最后一道限流

包发下去了不代表就完事。低端安卓机的 WebView 渲染弹幕,每秒超过 25 条就开始掉帧,超过 60 条整个页面卡死。

我们在客户端也加了一层:可见区域最多同时存在 32 条弹幕,超出的进本地缓冲队列,队列超过 120 条丢弃最旧的。滚动动画统一交给 CSS transform 走 GPU,不用 JS 逐帧改 left 值。开会时用户还会切后台,页面不可见就直接停止渲染只累计计数,切回来补一条"期间新增 xxx 条"。

这一段最容易被忽略,很多团队服务端调得漂漂亮亮,最后卡在用户那台三年前的手机上。我们做兼容测试时会专门留两台低配旧机,一台安卓一台老款平板,谁写的渲染逻辑都得先在这两台上跑通再说。整套直播弹幕限流的验收,最后一关就在这两台破机器上。

四段阈值和实测 QPS 对照

------------
上游进水客户端本地节流单人 1.2 秒 / 本地队列 5 条峰值 3.8 万 QPS 削到 1.1 万
闸门双层令牌桶房间桶 1575 / 用户桶 3稳定放行 1200 QPS
泄洪道55 毫秒窗口合并单包 480 字节 / 每秒 18 帧出口 96.7 Mbps
下游河道渲染队列限长可见 32 条 / 缓冲 120 条低端机稳定 30 帧

我在西南一个会展中心踩的那次坑

今年 4 月 17 号下午三点二十,西南一个会展中心的产品发布会。我把窗口合并的时间调到了 20 毫秒,想让弹幕"更跟手"。

结果开场十分钟,客户端全线掉线重连。原因蠢得很:20 毫秒一个包,每秒 50 个包,长连接的心跳和业务包挤在一起,部分企业网络的中间设备判定成异常流量给掐了。当时我坐在导播台后面,脚边一堆临时拉的电源排插,耳机里同事一直在喊"又断了又断了",我手心全是汗。改回 55 毫秒之后立刻恢复正常。

说白了就是省那点"跟手感"惹的祸。弹幕早 35 毫秒到,没有任何一个观众能察觉,但连接断一次所有人都看得见。事后我们把这条写进了检查清单,摄行科技现在每场开播前都会核一遍合并窗口的值。

上线前还得盯这几个数

链路搭完不等于能扛。真正的直播弹幕限流方案,得配一套可观测的数字:入口拒绝率、令牌桶溢出次数、合并包平均条数、客户端渲染丢弃量,这四个指标缺一个都排不清故障。相关的指标口径,直播数据报告应该包含哪些指标 里列过一份,可以照着补。

部署形态也影响阈值。私有化部署的内网带宽通常比公网出口宽松,但机器数量固定,合并窗口可以缩短一点;混合云的话就得考虑跨云回源,混合云直播架构怎么兼顾安全与弹性 里的思路可以拿来对照着改。

另外,涉及用户发言内容的留存和审核,行业里有明确规范,工业和信息化部中国通信标准化协会 都有公开文件,做企业会议直播这块尤其得先合规再谈性能。摄行科技在给客户搭弹幕通道时,审核链路是默认打开的,不接受关掉。

想要一套能扛的方案就来聊聊

万人级的弹幕不是靠堆机器堆出来的,四段水位得配着调。摄行科技可以按您这场的在线规模、观众设备构成和网络环境,出一份带具体阈值的直播弹幕限流配置表,也能上门做一次压测勘场。有历史场次的弹幕数据最好,发给我们,摄行科技这边照着真实峰值算,比套模板准得多。

#摄行科技

📌 看完案例,需要专业活动影像团队帮你执行?

摄行科技 2018 年成立 · 8 年品牌资质 · 服务 3000+ 场企业活动

会议直播 · 照片直播 · 多机位拍摄 · 活动企业影像 · 覆盖全国 300+ 城市