邮件系统在单区单服里很容易实现:写一条收件箱记录即可。问题出现在跨服活动、合区、玩家迁移、全服补偿和渠道分区之后。发送方不一定知道玩家当前在哪个分片,收件箱可能正在迁移,重复投递会造成附件重复领取,投递失败又会引发客服工单。跨分片邮件路由架构的核心,是把“邮件意图”先写入全局投递流水,再由路由层找到收件箱权威位置,最后按幂等键投递。
典型场景
跨服天梯赛结束后,系统要给来自 80 个分片的玩家发排名奖励。活动服只知道 playerId 和奖励内容,不知道玩家是否已经转服、合区或被封禁。某些玩家的收件箱正在从旧分片迁到新分片,某些分片临时不可用。如果活动服直接调用各区邮件接口,失败重试会非常混乱。更稳的做法是活动服提交 deliveryIntent,全局邮件路由服务按 player directory 查找当前 inboxOwner,并把投递任务送到对应分片。
架构示意
flowchart TD
E["Event Reward Service"] --> I["Delivery Intent Store"]
I --> R["Mail Router"]
R --> D["Player Directory"]
D --> R
R --> S1["Shard A Inbox"]
R --> S2["Shard B Inbox"]
R --> M["Migration Hold Queue"]
S1 --> L["Delivery Ledger"]
S2 --> L
发送意图先落全局流水
跨分片邮件不要由业务方直接循环调用分片接口。业务方提交 deliveryIntent,包含 mailTemplate、附件、收件人、业务来源、幂等键和过期策略。意图落库成功后,业务方即可认为奖励进入投递系统。后续路由、重试和失败告警由邮件平台处理。这样跨服活动不需要理解每个分片的瞬时状态。
玩家目录是路由依据,收件箱有唯一 owner
邮件路由依赖 player directory,目录记录玩家当前归属分片、迁移状态、封禁状态和收件箱 owner。收件箱 owner 可以是玩家归属服,也可以是独立邮箱服务,但同一玩家同一时刻必须唯一。若目录显示 migrating,路由器不要强行投递到旧服或新服,而应进入迁移等待队列。
投递幂等键必须跨分片稳定
同一封奖励邮件在重试、迁移前后、路由器故障恢复后都可能再次投递。幂等键不能使用分片本地自增 id,而应由业务来源、活动 id、玩家 id、奖励阶段组成。收件箱写入时先检查 deliveryKey,已存在则返回成功。附件领取再使用 mailId 和 claimId 防重,避免投递和领取两层混在一起。
迁移期间要冻结路由,不冻结意图
玩家转服或合区时,收件箱数据迁移可能持续数分钟。此时新邮件意图仍可接收,但路由应进入 hold 状态,等待目录切换完成后投递到新 owner。不要要求所有业务在迁移期间停止发邮件;业务很难做到,也容易漏补偿。冻结路由层比冻结业务层更可靠。
失败处理要区分临时不可达和永久拒收
分片短暂不可用、网络错误、写入超时属于临时失败,应按退避重试;玩家不存在、奖励配置非法、附件超过限制属于永久失败,需要进入死信和人工处理;玩家封禁是否接收邮件要看业务策略。失败原因分类清楚,运营才能判断是等待系统恢复,还是需要重新发放。
关键设计取舍
| 维度 | 架构处理 | 重点风险 |
|---|---|---|
| 全服补偿 | 批量意图加分片限速 | 避免压垮邮箱服务 |
| 跨服奖励 | 按玩家目录路由 | 迁移和合区 |
| 玩家转服 | hold queue 等待 owner 切换 | 旧新服重复投递 |
| 邮件领取 | 本地收件箱幂等领取 | 附件防重复 |
落地检查清单
- 跨服业务只提交 deliveryIntent,不直连分片邮箱
- player directory 维护 inboxOwner 和迁移状态
- deliveryKey 跨分片稳定且写入幂等
- 迁移期间邮件进入 hold queue
- 失败原因分为临时、永久和策略拒收
一线排障与复盘建议
这个架构上线后,团队要提前准备几类排障入口。第一是按玩家、业务单号或场景 id 查询完整链路,能看到请求进入、状态变化、关键版本、外部依赖结果和最终响应。第二是按时间窗口查看异常分布,区分是全局配置错误、单分片容量问题,还是少量玩家边界条件触发。第三是保留人工修复入口,但修复入口必须写审计流水,记录修复前状态、修复后状态、操作人、审批单和影响范围。没有审计的手工修复,短期能救火,长期会破坏系统可信度。
容量评估也要贴近玩法节奏,而不是只看平均在线。运营开活动、赛季结算、跨服匹配、周常刷新和主播带队都会让请求集中到很短窗口。压测脚本应模拟重复点击、弱网重试、服务超时、实例重启和消息乱序,不要只跑顺滑路径。对于玩家资产、资格、奖励、处罚这类敏感链路,压测结果里要额外检查幂等流水和最终状态,不只是吞吐量。
上线前可以采用影子模式:生产请求仍走旧逻辑,新架构旁路计算结果并记录差异。差异样本要由服务端、策划和客服一起看,因为有些差异来自旧逻辑 bug,有些来自新规则理解错误。等差异收敛后,再按小区服、低风险玩法或内部账号灰度。灰度期间观察错误码、超时、回滚次数、人工工单和玩家反馈,确认系统在真实噪声下仍然可解释。
路由目录与投递状态
PlayerDirectory 至少记录 playerId、homeShard、inboxOwner、migrationState、directoryVersion 和 updatedAt。MailRouter 每次投递都读取目录版本,并把 directoryVersion 写入投递流水。若投递失败后重试,路由器可以判断玩家是否已经迁移。如果目录版本变化,重算路由;如果没变化,按原 owner 重试。
DeliveryIntent 的状态建议包括 accepted、routing、held_for_migration、delivering、delivered、temporary_failed、dead_letter、cancelled。业务方查询投递结果时看到的是意图状态,不需要知道具体分片错误。分片邮箱只负责本地 inbox 写入和领取,跨分片复杂性留在路由层。
故障案例:合区期间重复补偿
一次合区活动中,系统给所有受影响玩家发补偿邮件。旧区服邮件任务已经投递一部分,新区服合并完成后运营又按新区名单重发。由于两边 mailId 都是本地自增,收件箱无法识别重复,部分玩家领取了两份补偿。
修复后,全局补偿邮件使用 deliveryKey = compensationId + playerId。无论投递到旧区还是新区,收件箱写入前都检查 deliveryKey。合区期间新邮件进入 hold queue,目录切换完成后统一投递。旧区已投递的邮件迁移到新区时保留 deliveryKey。这样重发任务也只会返回已投递结果。
大批量投递的节流
全服邮件和跨服奖励可能一次产生百万级意图。路由器不能瞬间把任务打到所有分片。需要按 shard、mailType、priority 做限速,并支持暂停某个分片。高优先级补偿可以先投递,低优先级营销邮件延后。每个分片邮箱服务也应暴露队列积压和写入延迟,路由器根据反馈调整速率。
附件邮件比纯文本邮件风险更高。附件投递成功不代表玩家已领取,领取才会改变资产。批量投递监控要区分 deliveredCount 和 claimedCount。运营看到领取率异常低时,可能是邮件入口问题,也可能是附件领取失败,不应混为一谈。
迁移与死信处理
迁移 hold queue 需要过期策略。正常迁移几分钟完成,若超过阈值仍未完成,应告警并阻止相关玩家完成转服,而不是让邮件意图无限堆积。死信队列也要分类:玩家不存在、模板不存在、附件非法、分片永久拒绝、超过最大重试。不同死信对应不同处理人,不能全部丢给研发。
人工重投时必须沿用原 deliveryKey,不允许生成新 key。若确实需要重新发一封不同邮件,应创建新的业务意图并说明原因。这样玩家资产和客服记录能保持一致。
上线验收指标
跨分片邮件上线后,要看 accepted、held、delivered、dead_letter 的漏斗。大量 held 可能说明迁移目录卡住,大量 temporary_failed 可能说明某个分片邮箱服务容量不足,大量 dead_letter 则说明业务模板或附件配置有问题。投递成功率要按 mailType 和 shard 分开看,全局平均值会掩盖单分片故障。
压测脚本要模拟百万级补偿、单分片不可用、玩家迁移中收到邮件、目录版本变化、路由器重启和人工重投。回滚策略是停止接收新的跨服意图,但继续处理已接受意图;如果路由层异常,可以把低优先级邮件暂停,高优先级补偿人工确认后投递。已经生成的 deliveryKey 必须保留,不能因为回滚而换一批 key。
团队协作边界
跨分片邮件涉及活动、平台、分区和客服团队。活动团队只关心奖励是否提交成功,平台团队负责路由和节流,分区服务负责本地收件箱,客服负责解释投递与领取状态。边界清楚后,某个分片不可用时不会让活动方重复发奖。
全服邮件发布前应提供预估收件人数、附件价值、优先级、过期时间和重投策略。高价值附件邮件必须经过小批量预投递,确认 deliveryKey、模板和附件都正确后再放量。
常见误区
第一个误区是让跨服活动直接调用各分片邮箱,失败后业务方自己重试。第二个误区是 mailId 使用分片本地自增,合区和迁移后无法识别重复。第三个误区是迁移期间拒绝业务发邮件,结果活动系统不得不补偿绕路。更稳的方式是接受意图、冻结路由、等待目录稳定后投递。
数据保留建议
跨分片邮件的 deliveryIntent、deliveryKey、路由目录版本和领取流水要分层保留。投递流水可以较早归档,但附件领取和补偿邮件要保留更久。合区、转服和跨服赛奖励经常在事后追查,缺少 directoryVersion 会很难判断邮件应该投到哪里。
总结
跨分片邮件最怕业务方各自补丁式投递。把发送意图、路由目录和收件箱 owner 分清楚后,邮件系统才能承受跨服活动和迁移带来的不确定性。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。