1.邮件系统架构设计总览
1.1 需求分析
游戏邮件系统是各大功能模块之间“物品与信息流转”的核心枢纽,需要满足多样化业务场景和高并发的可靠投递需求:
- 群发邮件 (Global Mail)
面向全服玩家统一投递,支持即时或定时发送,并管理邮件有效期与回收策略。 - 范围邮件 (Range-based Mail)
按照等级区间、公会、VIP、注册时间、活跃度等多维度筛选目标玩家,实现差异化内容投递。 - 指定目标邮件 (Targeted Mail)
针对单个或少数玩家发送,支持自定义附件、标题、正文,需校验收件人在线状态并实时反馈。 - 离线邮件 (Offline Mail)
离线玩家的奖励、补偿与物品暂存,上线后由客户端发起批量领取请求。 - 邮件中带附件
可能赠予玩家金币或者装备。 - 安全与合规
标准化物品发放流程、全链路操作日志、敏感词过滤与限速防刷。 - 高并发与可扩展
支持数万玩家并发收发,Mail 服可横向扩展,多实例动态路由,避免单点过载。
1.2 设计思路
采用分层解耦和组件化设计,邮件系统将各职责严格拆分,确保各层功能专一、互不干扰,从而提升可维护性与扩展性:
- 客户端:负责 UI 渲染、用户交互、协议的封包/解包、异步调用与日志输出,保持轻量化且专注于体验层面;
- Gate 服务器:作为唯一外网入口,统一管理会话生命周期与鉴权,利用
RouteComponent
透明路由,所有客户端请求和服务器推送均通过 Gate 中转,保证安全与可控; - Mail 服务器:专注核心邮件业务,包括离线邮箱管理、投递策略(全服、分区、指定目标)、定时过期清理、在线实时推送及状态同步;
- 数据存储层:采用 MongoDB 等持久化存储
MailUnit
、MailComponent
、MailBox
等实体,实现数据与逻辑分离,支持高效离线邮件读取与持久化; - 其他服务器:如活动、交易或战斗逻辑服,通过内网调用 Mail 接口批量发信;反之,Mail 服也可调用道具和货币服务,实现附件发放·清算等操作。
核心原则:客户端无须直连 Mail 服,Mail 服不暴露外网端口;所有请求与响应统一经由 Gate 转发,确保系统安全、流量可控并易于监控。
在多服部署场景下,邮件服务器数量可灵活扩展:
- 无分区模式:所有玩家共享同一世界,无明确区服划分时,可横向部署多个 Mail 服,通过玩家 ID 对服务器数量取模(
playerId % mailServerCount
)进行路由,或结合动态负载均衡,将玩家分配至负载较低的节点,防止单点过载并提升响应速度; - 分区服模式:每个区服独立运行,邮件交互频率相对较低,可为每个区服部署单个 Mail 服务,避免跨区复杂度,简化运维。
通过上述策略,既可保障邮件服务的高可用与高并发处理能力,也能在不同规模的游戏架构中实现灵活部署与运维优化。
1.3 架构图概览
graph LR subgraph 客户端 direction TB MailClientScene["MailClientScene"] ClientSession["ClientSession"] MailClientScene -->|"创建"| ClientSession end subgraph Gate服 direction TB GateScene["GateScene"] GateSession["GateSession"] GateUnitFlag["GateAccountFlagComponent"] RouteComp["RouteComponent"] GateScene -->|"创建"| GateSession GateSession -->|"挂载"| GateUnitFlag GateSession -->|"绑定路由"| RouteComp end subgraph Mail服 direction TB MailScene["MailScene"] UnitMgr["MailUnitManageComponent"] BoxMgr["MailBoxManageComponent"] MailUnit["MailUnit"] MailComp["MailComponent"] MailBox["MailBox"] Mail["Mail"] MailScene -->|"挂载"| UnitMgr MailScene -->|"挂载"| BoxMgr UnitMgr -->|"管理"| MailUnit MailUnit -->|"组件"| MailComp BoxMgr -->|"管理"| MailBox MailComp -->|"引用 聚合"| Mail MailBox -->|"引用"| Mail end %% 消息流 ClientSession -->|"C2G_LoginRequest"| GateSession GateSession -->|"G2Mail_LoginRequest"| MailScene MailScene -->|"Mail2G_LoginResponse"| GateSession GateSession -->|"G2C_LoginResponse"| ClientSession ClientSession -->|"C2Mail_SendMailRequest"| GateSession GateSession -->|"Route → MailUnit"| MailUnit MailUnit -->|"Mail2C_HaveMail / Mail2C_MailState"| GateSession GateSession -->|"Route → 客户端"| ClientSession
1.4 核心模块职责
客户端
- 初始化MailClientScene、创建管理
Session
连接与心跳。 - 使用
C2G_LoginRequest
发起登录请求并等待C2G_LoginRequest
响应。 - 绑定 UI 按钮,实现登录、获取邮件、打开邮件、领取附件、删除邮件、发送邮件等操作。使用
session.Call(new C2Mail_*Request)
发起 RPC,接收Mail2C_*Response
并处理日志输出。 - 注册
Mail2C_HaveMailHandler
与Mail2C_MailStateHandler
,接收服务器推送的邮件列表与状态变更。 - 渲染邮件列表与详情,展示
MailSimplifyInfo
与MailInfo
。
Gate 服务器
会话绑定
GateAccountFlagComponent
将Account
与Session
关联,用于合法性校验与下线通知。
跨服路由
RouteComponent
维护RouteType.MailRoute → MailUnitRouteId
,透明转发客户端消息到 Mail 服及回传响应。
上下线联动
- 登录时
GateLoginHelper.Online
通知 Mail 服创建/更新MailUnit
; - 退出时
GateLoginHelper.Offline
通知 Mail 服保存/移除MailUnit
。
- 登录时
GateAccount管理
- 正常来说是有一个
GateAccountManageComponent
管理所有GateAccount的。参考聊天系统中的Gate服设计,这里专注于邮件实现顾略过。
- 正常来说是有一个
Mail 服务器
MailUnit 管理
MailUnitManageComponent
挂载到MailScene上,加载/保存所有MailUnit
,维护在线缓存,缓存了所有的MailUnit
。包括所有的,在线的,离线的。可以用不同的数据结构缓存,方便其他地方获取。- 处理
G2Mail_LoginRequest
与G2Mail_ExitRequest
,完成用户登出与离线逻辑。
邮箱以及邮件快递盒数据结构设计
Mail 实体
OwnerId
:邮件所属玩家的唯一标识(AccountId/UnitId),用于将邮件与具体玩家关联。Title
、Content
:邮件的标题与正文,支持文本、富媒体等多种格式。CreateTime
、ExpireTime
:分别记录邮件生成和失效时间,用于后续的过期清理。Money
、Items
:邮件附件中的货币和物品列表,支持多种类型的奖励发放。MailState
、MailType
:状态(未读/已读/未领取/已领取)与类型(系统/奖励/玩家邮件)枚举,方便业务分支处理。
MailBox 实体
Mail
:嵌套的Mail
实例,实际承载邮件内容与附件。CreateTime
、ExpireTime
:同样记录邮件箱的生命周期,邮件过期后整体回收。MailBoxType
:枚举区分投递策略(指定目标/在线/全服/分区限时等),决定分发逻辑。AccountId
:所有待领取玩家的 ID 集合,支持一对多或批量发放场景。Received
:已领取玩家的 ID 集合,用于防止重复领取并在所有目标领取后自动清理掉整个MailBox
。SendAccountId
:发件人账号 ID,便于记录与审计操作来源。
Item 实体
Name
:邮件附件物品的名称,后续可扩展更多属性(模板 ID、数量、稀有度等)。
邮箱管理
MailBoxManageComponent
挂载到MailScene上,可以理解为邮件物流中转中心,用来存放所有离线的邮件。初始化时要从数据库加载所有未过期MailBox
,按类型与接收者索引添加到缓存中。- 定时任务
RepeatedTimer
检查过期邮件并调用Remove
清理; GetHaveMail
实现离线邮件批量领取。在MailUnit
登录时,尝试领取离线邮件。会遍历全服邮件和全服限时邮件,没过期就给玩家领。然后再去查询有没有指定给当前登录玩家的邮件,有就个玩家领。
邮件组件
- 挂载到MailUnit上的。
MailComponent
维护邮件id映射到邮件实体的的邮件字典,支持Add
(投递)、Remove
(删除)、OpenMail
(标记已读)、Receive
(领取附件)、CheckTimeOut
(过期清理)。可以设置邮件最大数量和过期时间。添加移除邮件时维护一个时间排序列表方便过期清理。
- 挂载到MailUnit上的。
消息处理
一系列
RouteRPC
Handler:C2Mail_SendMailRequestHandler
(发送邮件)C2Mail_GetHaveMailRequestHandler
(获取邮件列表)C2Mail_OpenMailRequestHandler
(打开邮件)C2Mail_ReceiveMailRequestHandler
(领取附件)C2Mail_RemoveMailRequestHandler
(删除邮件)
Other2Mail_SendRequestHandler
处理跨服投递请求;G2Mail_TestMessageHandler
示例自定义消息。
统一投递接口
MailHelper.Send
判断运行场景,调用InnerSend
(本地 Mail 服)或跨服路由,支持多种MailBoxType
分发策略:- Specify:针对特定玩家或玩家集;
- Online:仅在线玩家;
- All:全服玩家,批量投递并持久化;
- AllToDate:注册时间与邮件创建时间对比,定向投递;
1.5 总结
- 分层解耦:客户端、Gate、Mail、存储层各司其职,职责清晰,降低耦合。
- 组件化设计:MailUnit、MailBoxManage、MailComponent 等模块化系统,便于单元测试与热更新。
- 透明路由:Gate 的
RouteComponent
+ MailScene 的RouteRPC
,实现跨服透明投递与响应。 - 高可用架构:离线投递、定时过期清理、无状态网关设计,支持横向扩展与容灾。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com