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上的。
消息处理
一系列
RouteRPCHandler: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