消息队列详细设计架构文档
前言
本文是游戏业务线消息队列中间件详细架构设计文档,用于指导消息队列中间件后续的开发、测试和运维。
词汇表
Netty:开源的网络编程框架
Reactor:网络编程模型
Sharding:数据分片存储方案
Zookeeper:开源的分布式高可靠性云应用
Persistent Nodes:ZooKeeper 永久节点
Ephemeral Nodes:ZooKeeper 临时节点
1. 业务背景
随着游戏业务的加速发展,业务上拆分的子系统越来越多。由于历史原因,各系统之间使用的协议多种多样,并且都是接口方式的同步调用,由此带来几个明显的系统问题:
性能问题:
当游戏发布时,“运营子系统”要通知“包管理子系统”、论坛、App、Web 站点等多个系统,往往出现同步调用导致的发布时延较高,性能较低等问题。
当玩家充值时,“充值子系统”要通知 “VIP 子系统”,“VIP 子系统”判断玩家达到相应 VIP 等级后,需要通知“福利子系统”、“客服子系统”、“商品子系统”等多个系统,流程冗长,性能很低。
耦合问题:当新增一个子系统时,各相关子系统都要开发新的接口,耦合严重。
效率问题:每个子系统提供的接口参数和实现都有一些细微的差别,导致每次都需要重新设计接口和联调接口,开发团队和测试团队花费了许多重复工作量。


基于以上背景,我们需要引入消息队列实现消息异步化,进行系统解耦,提升系统间协同效率。
2. 约束和限制
3. 总体架构
3.1 架构分析
3.1.1 高可用
游戏版本发布和 VIP 业务都是高优先级业务,如果不能保证高可用,将造成用户体验断崖式下降,从而导致收入损失。而相比普通用户,VIP 用户群体更加注重服务可用性。所以综合来看,消息队列需要高可用性,包括消息写入、消息存储、消息读取均需要保证。
3.1.2 高性能
游戏新版本发布和用户充值不属于高频场景,故不需要保证超高性能,满足正常使用即可。
3.1.3 可扩展
消息队列主要使用场景为解耦、异步、削峰填谷,对目前主要业务场景来说,解耦和异步是系统最需要的,只要符合这些功能需求,后续无需扩展功能。
3.1.4 成本
随着游戏行业景气度上升,新游版号发放加速,业务加速发展,所以开发时间不能太长,开发成本不能太高。
3.1.5 安全
用户充值交易信息涉及少量用户隐私敏感信息,如充值付款账号、户名等等,需要考虑数据脱敏存储和对应的加解密措施。
3.2 总体架构
经过备选架构决策,最后决定使用的方案是“自研集群 + MySQL存储”。


4. 详细设计
4.1 核心功能
4.1.1 消息发送流程

4.1.2 消息消费流程

4.1.3 服务器主从切换
4.2 关键设计
4.2.1 消息发送可靠性
业务服务器中嵌入消息队列系统提供的 SDK,SDK 支持轮询发送消息,当某个分组的主服务器无法发送消息时,SDK 挑选下一个分组主服务器重发消息,依次尝试所有主服务器直到发送成功;如果全部主服务器都无法发送,SDK 可以缓存消息,也可以直接丢弃消息,具体策略可以在启动 SDK 的时候通过配置指定。
如果 SDK 缓存了一些消息未发送,此时恰好业务服务器又重启,则所有缓存的消息将永久丢失,这种情况 SDK 不做处理,业务方需要针对某些非常关键的消息自己实现永久存储的功能。
4.2.2 消息存储可靠性
消息存储在 MySQL 中,每个分组有一主一备两台 MySQL 服务器,MySQL 服务器之间复制消息以保证消息存储高可用。如果主备间出现复制延迟,恰好此时 MySQL 主服务器宕机导致数据无法恢复,则部分消息会永久丢失,这种情况不做针对性设计,DBA 需要对主备间的复制延迟进行监控,当复制延迟超过 30 秒的时候需要及时告警并进行处理。
4.2.3 消息如何存储
每个消息队列对应一个 MySQL 表,消息队列名就是表名,表结构设计大致如下:
4.2.4 消息内容安全
SDK 提供消息明文字段脱敏功能,可根据传入参数,将指定参数进行脱敏处理,具体脱敏规则可由业务方自行扩展接口实现。
4.3 设计规范
5. 质量设计
5.1 消息队列管理后台
为了方便维护,需建设消息队列管理后台系统,用于完成集群管理、消费队列配置、重复消费等等功能。集群启动后,消息队列服务器应主动向消息队列管理后台上报机器信息。消息队列管理后台负责维护集群配置信息,并定期下发配置和命令给消息队列服务器。

5.2 成本
研发 * 6 人
服务器
消息队列服务器 * 6 台
MySQL * 6 台
消息队列管理后台 * 2 台
6. 演进规划
6.1 消息队列一期
3 个月内完成系统建设,实现消息队列系统消息发送、消息存储及消息读取功能。
6.2 消息队列二期
2 个月内完成迭代,实现消息有序、队列监控、告警、死信队列、半自动扩缩容功能。