Q24: 如何设计广播机制?如何优化大规模广播?
核心结论
广播的本质不是“把一条消息发给很多人”,而是“在正确的范围、正确的时间、用合适的代价把信息分发出去”。
真正的大规模广播优化,第一步通常不是压榨网络库,而是先减少不该发的消息:
- 不该看到的人不要发
- 不重要的状态不要高频发
- 不同消息不要用同一种广播策略
如果范围控制没做好,后面的压缩、批量、异步发送都只能止损,不能从根上解决问题。
一、先把广播分类型
广播至少可以分成四类:
1. AOI 内局部广播
例如:
- 移动
- 技能表现
- 实体创建与销毁
- 血量、朝向、Buff 变化
这是 MMO 最常见的一类,也是流量大头。
2. 逻辑域广播
例如:
- 房间内广播
- 队伍广播
- 副本广播
- 公会广播
它的接收范围通常是显式集合,不完全依赖空间位置。
3. 全局或大区广播
例如:
- 系统公告
- 跨服活动通知
- 排行榜结算
这类消息频率低,但覆盖范围广。
4. 内部服务广播
例如:
- 配置热更通知
- 节点状态变化
- 订阅事件分发
这类广播未必面向玩家连接,但同样会带来扩散成本。
广播要先分类,否则会把所有问题都错当成“网络发送优化”。
二、广播最大的成本来自哪里
很多人直觉上觉得广播瓶颈在 socket send,但工程里常见的大头其实是:
- 接收者集合计算
- AOI 查询
- 序列化和拷贝
- 多连接上的重复编码
- 跨节点重复转发
尤其是位置和战斗状态广播,如果每次都重新查所有接收者、重新组包、逐连接编码,开销会很快失控。
三、优化第一原则:先缩小广播范围
1. AOI 裁剪
最基础也最有效。
只有真正看得到、需要知道该消息的玩家才应该收到。
这要求 AOI 系统不仅能回答“谁在附近”,还要能较低成本地维护:
- 进入集合
- 离开集合
- 持续可见集合
2. 逻辑分组
队伍、房间、公会、战场等逻辑域不要每次临时扫描全服,应提前维护成员集合。
3. 按重要性降频
并不是所有状态都值得高频广播。
例如:
- 位置和朝向高频
- 血量中频
- 属性面板低频
- 非关键装饰状态更低频
如果所有字段都跟着位置同频率广播,带宽很快会爆。
四、优化第二原则:区分事件和状态
广播常常混着两类完全不同的内容:
- 事件,例如施法、死亡、掉落、升级
- 状态,例如位置、HP、朝向、当前动作
这两类消息适合的策略不同:
- 事件更强调可靠送达和顺序
- 状态更强调最新、可覆盖、可插值
如果用同一种可靠广播策略处理两者,要么状态广播过重,要么关键事件不够稳。
五、常见优化手段
1. 批量发送
在一个 tick 内,把多个小更新合并成一批再发,通常比每次变化立刻发更省:
- 系统调用更少
- 包头占比更低
- 更容易做压缩
但批量窗口不能过大,否则会增加感知延迟。
2. 脏字段与增量同步
很多消息只改了少数几个字段,没必要整对象重发。
常见做法是:
- 标记脏字段
- 广播版本号或变化掩码
- 客户端按字段合并
3. 多连接复用同一份编码结果
如果同一条广播要发给很多连接,不要对每个连接都重新序列化一遍。
更好的做法通常是:
- 先编码一次共享消息体
- 每个连接只补少量头部或引用
4. 分层转发
大范围广播不要总由单节点直推所有连接,常见做法是:
- 先按场景、分区、网关分发
- 再由边缘节点向本地连接扇出
这样更容易:
- 降低跨机流量
- 控制故障域
- 缩短单点热点链路
六、AOI 广播为什么经常最难
因为它同时要求:
- 高频
- 低延迟
- 范围动态变化
- 接收者集合与空间位置强相关
一个移动事件触发后,系统往往不仅要广播位置变化,还要判断:
- 哪些玩家新看到该实体
- 哪些玩家看不到了
- 哪些玩家仍在可见范围内
因此 AOI 广播优化往往要和 AOI 数据结构一起设计,而不是事后补丁。
七、大规模广播时如何避免风暴
1. 避免全服瞬时扇出
例如世界公告、活动开启通知,尽量不要让一个中心节点同步推给所有在线用户。
更稳妥的方式是:
- 网关分层下发
- 分片并行发送
- 必要时做平滑扩散
2. 给广播做优先级
在发送队列拥塞时,应该明确哪些消息可以延后、合并甚至丢弃。
例如:
- 关键事件优先
- 高频位置更新可覆盖旧包
- 非关键提示可降级
3. 控制背压
慢连接不能无限拖累发送队列。对明显跟不上的连接,系统需要具备:
- 丢弃过期状态消息
- 降频
- 断开保护
否则一个少数慢连接就可能拖垮广播链路。
八、工程上常见的稳妥组合
很多 MMO 最后会收敛成类似策略:
- AOI 内状态广播:增量加批量,位置类消息可覆盖旧版本
- 关键战斗事件:可靠有序广播
- 全局通知:分层转发
- 网关侧:每连接队列和背压控制
- 服务端:按场景或分区聚合接收者集合
重点始终是先分类型,再决定每类消息的频率、可靠性和传播范围。
九、常见误区
1. 广播优化就是消息压缩
压缩有用,但不是第一位。范围控制通常比压缩更重要。
2. 广播越实时越好
不对。很多低价值消息即使晚几十毫秒,对体验也没影响,却会显著增加系统成本。
3. 广播只和网络层有关
不对。AOI、数据建模、脏字段管理、网关分层、发送队列策略都会决定广播质量。
参考资料
- Glenn Fiedler, Snapshot Compression / Snapshot Interpolation
- 各类 MMO AOI 与广播系统设计实践资料
