架构师实战营 模块三作业(基于自研集群 + MySQL 存储的消息队列系统架构设计文档)
题来源于架构实战营模块三第 5 课内容。
模板参考:https://xie.infoq.cn/article/a1c01e8f55c81b36a787f9f5b
基于 MySQL 的消息队列架构设计文档
前言
本文是游戏开发平台消息队列中间件详细架构设计文档,用于指导后续消息队列的开发、测试和运维。
词汇表
Reactor:网络编程模式
Netty: 开源网络编程框架
Zookeeper:分布式主备服务器集群主备切换服务器
Tomcat: 消息队列系统服务器
MySQL:消息队列关系数据库
1. 业务背景
游戏业务发展很快,系统越来越多,但系统间协作效率很低。
比如新版本发布了,运营要通知到 App、Web 站点等及时更新到新版本。
比如玩家充钱了,充值子系统要通知 VIP 子系统,VIP 子系统要判断玩家等级,达到 VIP 后,通知福利子系统进行奖品发放。消息使用很多。
性能问题:要同步消息到多个系统,没有消息队列,各模块自己通信,效率低。
耦合问题:新增子系统后,要开发新接口用于通信。
效率问题:各子系统接口参数和实现有区别,导致每次都要重新设计接口,联调接口,开发和测试都耗费了大量工作。
基于以上背景,需要用消息队列对系统进行解耦,将同步调用改为异步通知。
2. 约束和限制
时间:2021 年 9 月 30 日前完成
成本:不能超过 1000 万
范围:监管方要求使用 Oracle,技术选型要可靠
质量:符合 ISO9001 标准
3. 总体架构
系统边界白盒图如下:
Rank 分为生产者服务器,消息队列服务器,以及消费者服务器。生产者的 role 是发送消息,消费者接受消息。Relation 如图所示,从生产者发到消息队列服务器,再发到消费者服务器。
3.1 架构分析
3.1.1 高性能
不需要。游戏业务的 vip 充值等消息并不会很多,所以不需要高性能。并发度也不高,所以可以在满足其他条件下,尽可能达到高性能即可。
3.1.2 高可用
需要。对微博子系统来说,如果消息丢了,导致没有审核,触犯国家法律法规,是很严重的事情。对等级自己同而言,如果用户到了 VIP,但是没有给奖品和专属服务,会导致用户流失。但审核子系统要求更高。
3.1.3 可扩展
不需要。消息队列功能相对稳定,不需要可扩展。
3.1.4 成本
需要控制,尽可能保证质量的情况下,投入较少的成本进行研发。
3.2 总体架构
采用数据分片架构,每个分片的集群中的服务器进行分组,每个分组存一部分数据。每个分组有 MySQL 的主备服务器。
3.2.1 客户端 Role
客户端可以用 Java 语言开发,基于 Netty 实现与服务端的交互。用轮询的方式写入和读取消息。
3.2.2 服务端 Role
服务端基于 Netty 开发,采用 Reactor 网络模型。
消息队列管理后台可以用 Java 开发,或者 Go 开发。
MySQL 服务器分为主备,主服务器负责读写,从服务器只能读取数据,不能写。在 MySQL 的主备服务器间有同步操作。
3.2.3 客户端和服务端的 Relation
客户端和
3.2.4 MySQL 的 Role 和 Relation
采用 MySQL 主同步。
消息最多存 2 个月的,过期的自动删除。
4. 详细设计
4.1 核心功能
客户端分为生产者和消费者两种 Role。服务端的 Netty 会处理相应数据。
4.1.1 消息发送流程
不同的消费者先发消息到消息队列的 Netty,接收后根据路由通知到相应的接收服务器。让接受服务器从 MySQL 中读取数据。管理系统会读取所有服务器信息。消息队列会根据范围分片存在相应的服务器上。
4.1.2 消息消费流程
消费者受到消息后,从 MySQL 服务器根据分片,读取数据。
4.2 关键设计
1)消息发送可靠性
业务服务器中嵌入消息队列系统提供的 SDK,SDK 支持轮询发送消息,当某个分组的主服务器无法发送消息时,SDK 挑选下一个分组主服务器重发消息,依次尝试所有主服务器直到发送成功;如果全部主服务器都无法发送,SDK 可以缓存消息,也可以直接丢弃消息,具体策略可以在启动 SDK 的时候通过配置指定。
如果 SDK 缓存了一些消息未发送,此时恰好业务服务器又重启,则所有缓存的消息将永久丢失,这种情况 SDK 不做处理,业务方需要针对某些非常关键的消息自己实现永久存储的功能。
2)消息存储可靠性
消息存储在 MySQL 中,每个分组有一主一备两台 MySQL 服务器,MySQL 服务器之间复制消息以保证消息存储高可用。如果主备间出现复制延迟,恰好此时 MySQL 主服务器宕机导致数据无法恢复,则部分消息会永久丢失,这种情况不做针对性设计,DBA 需要对主备间的复制延迟进行监控,当复制延迟超过 30 秒的时候需要及时告警并进行处理。
3)消息如何存储
每个消息队列对应一个 MySQL 表,消息队列名就是表名,表结构设计为 user ID,VIP level, game info, account info 等。
4.3 设计规范
1)消息队列服务器使用 Spring Boot + Netty 开发框架。
2)MySQL 使用 Innodb 存储引擎。
3)连接协议采用 TCP,TCP 包的结构设计采用 JSON 格式,采用 SSL 加密。
4)需要支持 HTTPS 接口。
5. 质量设计
5.1 可测试性
可以查看队列的消息深度,分片的情况。
可以查看具体消息内容
可以修改消息状态
主备切换
增减分片
5.2 可维护性
清空队列
重启队列
5.3 可观测性
观测队列深度
直观显示出 CPU,内存,磁盘 IO,网络使用量
5.4 成本
第一版采用两个分片。
6. 演进规划
6.1 消息队列一期
保证业务基本通信需求的实现。
6.2 消息队列二期
完善系统监控,可以直观看到系统的运行情况,如队列深度,CPU、内存、磁盘、网络的消耗。
系统性能优化。
6.3 消息队列三期
如果需求量大增,考虑用 Kafka 等成熟的消息队列方案替换 MySQL。
评论