思考(四十四):一种全服邮件的实现方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013272009/article/details/82957297

背景假设

  • 考虑到大量玩家在线、以及更多未在线玩家
  • 并假设逻辑服是可以多开的
  • 本文只针对 全服邮件 的发送实现,如读邮件、提取附件、删邮件等等同简单玩家邮件

本文术语

  • GMTool

    能够发送 全服邮件 的客户端

  • GMServer

    给 GMTool 提供服务的服务器程序

  • LogicServer

    处理游戏客户端逻辑的服务器程序

实现

下面分几个步骤说明:

一、创建 全服邮件

有 2 种情况:

  • LogicServer 运行中
GMTool GMServer Redis LogicServer 1. 发送一封 `全服邮件` 2. 检查删除过期 `全服邮件` 2. 保存这封 `全服邮件` 3. 通知 `全服邮件` 到达 3. 通知 `全服邮件` 到达 3. 维护 `全服邮件` 列表 3. 触发处理 `全服邮件` 逻辑 GMTool GMServer Redis LogicServer
  • LogicServer 启动时
LogicServer Redis 1. 获取 `全服邮件` 列表 1. 返回 `全服邮件` 列表 1. 本地删除过期 `全服邮件` 2. 通知 `全服邮件` 到达 3. 维护 `全服邮件` 列表 3. 触发处理 `全服邮件` 逻辑 LogicServer Redis

二、全服邮件 发送队列

有 2 种情况:

  • 离线玩家登录
Client LogicServer Redis 1. 玩家登录逻辑处理(略) 1. 获取玩家接收过 `全服邮件` ID 列表 1. 返回该玩家接收过 `全服邮件` ID 列表 2. 依次检查 该玩家是否已接收过 `全服邮件`列表中的邮件 3. 如果未接收过,加入 该`全服邮件`发送队列 Client LogicServer Redis
  • 在线玩家
LogicServer 1. 通知 `全服邮件` 到达 2. 依次检查在线玩家 是否已接收过该邮件 3. 如果未接收过,将玩家加入 该`全服邮件`发送队列 LogicServer

三、发送队列中的单玩家处理逻辑

单个玩家全服邮件发送逻辑,实现如下:

Client LogicServer Redis 1. `全服邮件` 发送队列中取出一个玩家 2. 保存玩家邮件 2. 返回保存结果 3. 维护该玩家接收过 `全服邮件` ID 列表 4. 通知新邮件到达 Client LogicServer Redis

更严谨点的话, 2 、3 处理应该在同一个事务中处理

即可以使用 Redis Lua 或者 Reids Module 来使 2 、3 两个步骤做成一个事务

四、全服邮件 发送队列处理频率

处理频率主要约束条件是 Redis 的处理能力。

部署 Redis 的机器性能、 Redis 的部署方式是否集群化等,都会执行影响 处理频率。

下面分析下单 Redis 情况:

假设:

  • 每次处理 10 个玩家
  • 每次处理时间间隔 25ms
  • Redis 每秒处理 10w 次保存操作

则:

  • LogicServer 在线 4000 玩家, 10 秒发送完毕
  • 单 Redis 支持 100 万玩家在线,需要开 250 台 LogicServer,并在 10 秒发送完毕

通用的全服邮件服务

上面分析中,时序图中,涉及 5 个对象:

  • GMTool
  • GMServer
  • Redis
  • LogicServer
  • Client

GMTool 、 GMServer 、 Redis 已经很独立了。

LogicServer 、 Client 则与具体游戏相关。

要做通用的全服邮件服务,则可以抽象出 MailServer 。

从上述时序图中,可以看到, MailServer 需要知道:

  • 玩家登录、登出事件
  • 通知玩家新邮件到达、其他邮件事件(本文未涉及到,如读邮件、提取附件、删邮件)

因此需要对 对接服务器 提供 2 种接口

  • 告知 玩家登录、登出事件
  • 邮件事件投递, Client <-> 对接服务器 <-> MailServer

提供接口的话, Client <-> 对接服务器 无法控制,特别是 Client 需要知道具体 邮件协议,并做处理。

更进一步,比较友好的方式,则可以提供 2 个 SDK

  • 对接服务器 用的 SDK

    • 封装 告知 玩家登录、登出事件
    • 封装 邮件事件投递 的 Client <-> 对接服务器 <-> MailServer
  • 给 Client 用的 SDK

    • 封装 邮件事件投递 的 Client <-> 对接服务器 部分

以上

猜你喜欢

转载自blog.csdn.net/u013272009/article/details/82957297
今日推荐