写点什么

第三课作业

用户头像
杰语
关注
发布于: 2021 年 05 月 09 日

前言

游戏业务发展很快,系统也越来越多,系统间协作的效率很低,本文用于设计消息队列,用于系统之间解耦。


词汇表

1. 业务背景

随着游戏业务的快速发展,游戏系统越来越庞大,系统之间都是同步调用,耦合比较严重。由此带来较多问题,例如如下场景:

  • 新版本发布,游戏打包和发包。

  • 玩家充值和 VIP 奖品发放。

这些场景下都时同步调用,耦合严重,效率较低。由此,我们需要引入消息队列进行系统解耦,将系统中的同步调用修改为异步调用。


2. 约束和限制

  1. 成本不能太高。

  2. 有可用性。

  3. 必须符合现有的运维体系,可以嵌入现有的运维体系中。

  4. 不能使用阿里的机房体系,和现有的机房不能互通。

3. 总体架构

本架构采用自研消息队列,使用 MySQL 存储消息队列进行解耦。


3.1 架构分析

  • 高可用,消息需要不丢失,保持消息的顺序。

  • 性能,消息不需要太高的 QRT,MySQL 就能满足效率要求。

  • 可扩展,如果需要增加消息队列,只需要增加 sharding 极客。


3.2 总体架构

消息队列由若凡分组集群组成,每个分组包括一主一备,每主备都由消息服务器和 MySQL 服务器组成。其中:

1、主备的 MySQL 服务器进行主备复制,以保证存储消息不丢失,

  1. 当主用服务器发生故障时,主服务器和倍服务器之间发生倒换。

  2. 备服务器只能用于读,主服务器可以用于读写,当主服务器故障,读写都切换到备服务器。


4. 详细设计

4.1 核心功能

4.1.1 消息发送流程


4.1.2 消息消费流程


4.2 关键设计

1)消息发送可靠性

业务服务器中嵌入消息队列系统提供的 SDK,SDK 支持轮询发送消息,当某个分组的主服务器无法发送消息时,SDK 挑选下一个分组主服务器重发消息,依次尝试所有主服务器直到发送成功;如果全部主服务器都无法发送,SDK 可以缓存消息,也可以直接丢弃消息,具体策略可以在启动 SDK 的时候通过配置指定。

如果 SDK 缓存了一些消息未发送,此时恰好业务服务器又重启,则所有缓存的消息将永久丢失,这种情况 SDK 不做处理,业务方需要针对某些非常关键的消息自己实现永久存储的功能。

2)消息存储可靠性

消息存储在 MySQL 中,每个分组有一主一备两台 MySQL 服务器,MySQL 服务器之间复制消息以保证消息存储高可用。如果主备间出现复制延迟,恰好此时 MySQL 主服务器宕机导致数据无法恢复,则部分消息会永久丢失,这种情况不做针对性设计,DBA 需要对主备间的复制延迟进行监控,当复制延迟超过 30 秒的时候需要及时告警并进行处理。

3)消息如何存储

每个消息队列对应一个 MySQL 表,消息队列名就是表名,表结构设计为

key(int) + value(String)


4.3 设计规范

1)消息队列服务器使用 Spring Boot + Netty,

2)MySQL 使用 Innodb 存储引擎

3)TCP 包的结构设计,其中 netty 读取消息使用的消息格式为

消息头(FFFF 2 个字节) + 长度(int 2 个字节) + 消息体

5. 质量设计

5.1 消息队列管理后台

  1. 消息队列后台可连接应用服务器,查看应用服务器状态

  2. 可以查看每个应用服务器由多少个消息队列,每个队列有多少消息


5.2 成本

采用消息集群,每个消息应用一主一备,使用 4 台服务器。


6. 演进规划

第一期,完成基本的消息队列功能

第二期,完成多消息队列断点续传能力,消费完成后可记录当前消费点,下次消费可从消费点开始消费

用户头像

杰语

关注

还未添加个人签名 2018.01.30 加入

还未添加个人简介

评论

发布
暂无评论
第三课作业