微服务拆分实践
概述
单体重构到微服务,收益是独立扩展与故障隔离,代价是分布式一致性与运维复杂度。游戏行业往往不是"彻底微服务",而是"按需拆分":把热点、独立领域拆出来。本文以用户/房间/匹配/好友/商城服务为例,讲清拆分边界,并解决服务间数据一致性(Seata/TCC)。
一、服务拆分
1.1 拆分原则
拆分边界:
按领域(用户/社交/经济/对战)
按热点(排行榜独立扩展)
按团队/发布节奏
拆分决策:
数据内聚(一个服务管自己的库)
调用频率(高频低耦合可拆)
变更频率(独立发布)反模式警示:
拆分过细(分布式事务满天飞)→ 合并
为拆而拆(没有独立诉求)→ 保持单体
共享数据库 → 拆了个寂寞1.2 服务划分
游戏微服务划分:
用户服务:账号、玩家数据
房间服务:房间/对局
匹配服务:匹配池(高吞吐独立)
好友服务:好友/聊天
商城服务:商城/充值
排行榜服务:榜单(独立扩展)
运营服务:活动/公告
依赖关系:
房间/匹配 → 用户
商城 → 用户
排行 → 房间(事件)服务通信:
同步 RPC(强一致操作,见跨服通信章节)
异步 MQ(可延迟操作,见消息队列章节)
事件驱动(领域解耦)二、拆分要点
2.1 数据隔离
每个服务独立数据库(逻辑隔离):
用户库:player/currency/items
房间库:room/对局记录
好友库:friend/chat
商城库:order
数据同步:
跨服务数据通过事件/MQ 同步(非直接连库)
查询聚合 → 网关层聚合(BFF)2.2 状态归属
有状态服务(房间):
房间状态在房间服务(分片)
玩家跨服务操作 → 通过服务调用
无状态服务:
网关、匹配、排行榜 → 无状态扩展
匹配池状态可以 Redis 化(无状态化)玩家数据访问:
房间服务需要玩家信息(昵称/等级)→ RPC 查用户服务
高频热点 → 本地缓存快照(延迟同步)
对战结算 → 事件回传用户服务发奖三、分布式事务
3.1 一致性问题
微服务下的事务难题:
跨服务操作没有本地事务(各自独立)
例:下单扣款(商城服务)+ 发货(用户服务)
一致性选择:
强一致(同库/同事务)→ 避免跨服务事务
最终一致(异步 + 补偿)→ 大多业务
宽松一致性(可接受延迟)→ 统计类设计优先:
先设计"不跨服务"的操作(数据内聚)
必须跨的用可靠事件/补偿
避免分布式事务(尽量不用强一致 2PC)3.2 Seata
Seata 分布式事务方案:
AT 模式:自动补偿(基于 SQL 反向日志)
TCC 模式:手动补偿(Try-Confirm-Cancel)
Saga:长事务编排
AT 模式特点:
侵入小(注解 + 数据源代理)
适合短事务(秒级)
性能开销(全局锁)// Seata AT 模式示例
@GlobalTransactional
public void buyItem(long playerId, long shopId) {
orderService.createOrder(playerId, shopId); // 本地事务
userService.deductMoney(playerId, price); // 本地事务
itemService.addItem(playerId, itemId, 1); // 本地事务
// 任一步失败 → 全局回滚(反向补偿)
}3.3 TCC 模式
TCC 三个动作:
Try:预操作(冻结资源)
Confirm:确认(真正扣减)
Cancel:取消(释放冻结)
游戏场景:
下单:Try 冻结余额 → Confirm 扣款发货 / Cancel 解冻
特点:
可靠(可回滚)但开发量大
适合关键资金操作// TCC 接口设计
public interface MoneyService {
boolean tryFreeze(orderId, amount); // 冻结
boolean confirm(orderId); // 确认扣款
boolean cancel(orderId); // 解冻
}3.4 可靠事件(推荐)
可靠事件 + 本地消息表:
1. 本地事务:业务操作 + 写消息表
2. 异步投递消息 → 下游消费
3. 下游幂等消费(bizId)
4. 消息表扫描重投(未确认的)
5. 对账兜底
游戏实践:
扣款发货 → 本地事务 + 消息表 → 发货服务幂等消费
相比 Seata 更简单可靠(最终一致)四、微服务运维
运维复杂度:
服务注册发现(Nacos,见跨服章节)
网关聚合/路由(Spring Cloud Gateway)
监控(每个服务指标)
日志/链路追踪(见运维章节)
配置中心(统一管理)
发布:
服务独立发布(灰度)
版本兼容(接口演进)游戏特有考量:
延迟敏感(对局服务不能太细拆分)
房间服务保持有状态单体(内部分区)
微服务主要拆"外围"(统计/运营/社交)
核心对战链路尽量短(减少跨服务调用)五、实现要点
设计清单:
按领域/热点拆分(数据内聚)
同步 RPC + 异步 MQ + 事件解耦
数据隔离(每服务独立库)
一致性优先"可靠事件"(本地消息表 + 幂等)
强一致关键链路(扣款)→ Seata/TCC
避免过度拆分(对局链路保持紧凑)工程注意:
服务间调用超时/熔断(防雪崩)
幂等是最终一致的基石
对账任务兜底(定期核对)
版本兼容与灰度常见坑:
分布式事务滥用 → 性能与复杂度
服务间同步调用链过长 → 延迟叠加
数据重复(多服务各存一份)→ 同步与一致性
拆分后无法回滚 → 灰度 + 兼容与其他系统衔接:
RPC → 跨服通信章节
MQ → 消息队列章节
服务发现 → 跨服通信章节
监控 → 性能监控章节