微服务与分布式事务¶
一句话:微服务治理保证"服务多起来后不互相拖垮",分布式事务解决"跨服务/跨库的数据如何最终一致",两者是大型后端架构的两块硬骨头。
概念¶
微服务把单体拆成多个独立部署的服务,带来敏捷与隔离,但也带来远程调用的不可靠(网络抖动、超时、级联失败)和跨服务数据一致性两大难题。
微服务治理(注册中心 Nacos、声明式调用 Feign、熔断限流 Sentinel)解决的是"服务发现、负载均衡、故障隔离"。分布式事务(2PC、TCC、Saga、本地消息表)解决的是"一笔业务跨多个服务/库时,要么全成功要么全失败"。CAP 定理则给出了分布式系统在一致性与可用性间必须做出的根本取舍。
原理¶
微服务治理三件套¶
| 组件 | 职责 | 关键点 |
|---|---|---|
| Nacos | 注册中心 + 配置中心 | 服务注册发现、动态配置;AP/CP 可切换(默认 AP) |
| Feign/OpenFeign | 声明式 HTTP 调用 | 接口化调用远程服务,集成负载均衡(Ribbon/LoadBalancer)与熔断 |
| Sentinel | 流控/熔断/降级/系统保护 | 滑动窗口统计,保护服务不被打挂 |
治理流程:服务启动向 Nacos 注册 → 消费方从 Nacos 拉取服务列表 → Feign 按负载均衡选实例调用 → Sentinel 在调用前后做流控熔断。当某实例异常,Nacos 健康检查摘除实例,Sentinel 熔断慢调用,避免级联雪崩。
分布式事务方案对比¶
| 方案 | 原理 | 一致性 | 性能 | 复杂度 | 适用 |
|---|---|---|---|---|---|
| 2PC / XA | 协调者两阶段:准备+提交 | 强一致 | 差(长锁) | 中 | 传统 DB,少用 |
| TCC | Try-Confirm-Cancel,业务两阶段 | 强一致(最终) | 好 | 高(业务侵入) | 资金、库存等强一致 |
| Saga | 长事务拆成 N 步+补偿 | 最终一致 | 好 | 中 | 长流程业务 |
| 本地消息表 | 业务表+消息表同库写,轮询发送 | 最终一致 | 好 | 低 | 通用、最常用 |
| 事务消息 | RocketMQ 半消息+回查 | 最终一致 | 好 | 中 | 已用 RocketMQ |
TCC 三阶段:Try(预留资源,如冻结余额)→ Confirm(确认提交,扣减冻结)→ Cancel(取消,解冻)。需要业务为每个操作实现 Try/Confirm/Cancel 三个接口,且要保证幂等、空回滚、悬挂控制。
Saga:把长事务拆成一串本地事务 T1,T2...Tn,任一步失败则反向执行已成功步骤的补偿 C1,C2...。无资源预留,适合流程长的业务(如订单→支付→发货→通知)。
本地消息表:最朴素可靠。在业务库里建一张消息表,业务操作与消息插入在同一本地事务里,再用定时任务/Canal 扫描消息表发送到 MQ,消费者幂等处理。强依赖本地事务保证"业务与消息同生共死"。
TCC 的三个坑¶
| 坑 | 含义 | 应对 |
|---|---|---|
| 幂等 | Confirm/Cancel 可能被重试 | 每步带唯一事务 ID,记录状态,重复执行直接返回 |
| 空回滚 | Try 未执行却先收到 Cancel | Cancel 前查 Try 是否执行,未执行则记"空回滚"标记 |
| 悬挂 | Cancel 先于 Try 到达,之后 Try 又执行导致资源悬挂 | Try 前查是否已 Cancel,已 Cancel 则拒绝 Try |
CAP 定理¶
CAP 指分布式系统在 C(一致性)、A(可用性)、P(分区容错) 三者中,发生网络分区(P)时只能在 C 与 A 间选一个:
- CP:分区时宁可拒绝服务也要保证一致(Zookeeper、etcd、Redis Redlock 思路)。
- AP:分区时保证可用,允许短期不一致(Nacos 默认、Eureka、大多数互联网业务)。
工程现实:P 是必选(网络分区必然发生),所以本质是 CP vs AP 取舍。绝大多数高并发互联网业务选 AP + 最终一致性,因为可用性(保 SLA、保收入)比强一致更重要,一致性用补偿、消息、对账来最终达成。ACID 是单机/同库事务的强一致,BASE 是分布式场景的最终一致。
实战要点¶
结合报告"Nacos/Feign/Sentinel 服务治理、分布式事务与一致性设计"以及交易链路经验:
-
治理先于拆分:拆微服务前先把 Nacos 注册、Feign 调用、Sentinel 熔断限流这三件套建好,否则拆完就是一堆互相拖垮的服务。Feign 调用必须配超时与熔断,不能裸调。
-
强一致场景才上 TCC:资金扣减、库存扣减这类必须"要么全成要么全不成"的才用 TCC。TCC 业务侵入大(每个操作写三个接口),不要为追求"高大上"在弱一致场景用。报告项目交易链路的下单-扣库存-扣款用 TCC/本地消息表组合。
-
本地消息表是兜底通用方案:当不确定用哪种分布式事务时,本地消息表最稳——业务与消息同库事务,靠本地 ACID 保证一致性,MQ 异步通知下游,消费者幂等。能覆盖 80% 的最终一致场景。
-
必须配对账:所有分布式事务方案都不是 100%,线上必须跑定时对账(如每日对账脚本比对各服务状态),发现不一致人工或自动补偿。对账是分布式一致性的最后一道防线。
-
选 AP 保可用:交易大促选 AP,宁可局部短暂不一致(用对账修正),也要保 99.99% 可用。Nacos 用 AP 模式(Distro),注册信息最终一致但不会因一致性卡死服务发现。
-
补偿要幂等可重入:Saga/TCC 的补偿操作必须幂等,因为补偿本身也可能失败重试。每个业务步骤的状态机要清晰(待执行/已执行/已补偿)。
本节相关题目¶
| 难度 | 题目 | 链接 |
|---|---|---|
| 基础 | CAP 定理与取舍 | → 题库 |
| 进阶 | RocketMQ 事务消息两阶段 vs 本地消息表 | → 题库 |
| 深度 | 高并发分布式事务最终一致性、TCC 的坑与补偿设计 | → 题库 |