其他
跨微服务分布式事务用 Saga 模式实现补偿与编排(2PC…
在微服务间实现分布式事务、跨聚合长流程编排,用异步补偿替代两阶段提交,并处理卡死、重复执行、超时与补偿顺序问题。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 47/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 50/100 ×0.15
适用场景
跨微服务分布式事务用 Saga 模式实现通用
解决思路
- 明确服务边界与归属:确定每个步骤由哪个服务拥有。
- 梳理事务需求:区分哪些步骤必须原子、哪些可以最终一致。
- 为每个步骤定义失败模式:区分瞬时失败与永久失败,并制定重试策略。
- 为每个步骤设定 SLA 要求,用于推导超时配置。
- 确认现有事件/消息基础设施(Kafka、RabbitMQ、SQS 等)。
- 产出 Saga 定义:包含有序步骤、action 命令与 compensation 命令。
- 按所选模式实现 orchestrator 或 choreography。
- 为每个参与服务编写补偿逻辑,要求幂等且始终成功。
- 为每个步骤配置超时与各自的 deadline。
- 搭建监控:状态机指标、卡死 saga 检测、DLQ 恢复。
- 让每个步骤幂等——命令可能因 broker 重连被重放。
- 谨慎设计补偿逻辑——它是最关键的代码路径。
- 使用 correlation ID——saga_id 必须贯穿每个事件与日志。
- 实现每步超时——绝不要无限等待参与者回复。
- 记录状态转换——每次变更都记录 saga_id、step_name、old_state → new_state。
- 显式测试补偿路径——在集成测试中于每个步骤索引处注入失败。
- 不要假设立即完成——Saga 是异步的,可能耗时数分钟。
- 不要跳过补偿测试——回滚路径最难做对。
- 不要直接耦合服务——使用异步消息,绝不在 saga 步骤内做同步调用。
- 不要忽略部分失败——部分执行的步骤仍需补偿。
- 不要使用全局超时——每个步骤的延迟特性不同。
- 处理卡在 COMPENSATING 状态的 saga:为补偿消费者添加 DLQ 处理,并确保每个补偿动作即使底层操作已回滚也发布结果事件(例如捕获 ReservationNotFoundError 后视为成功,始终发布 SagaCompensationCompleted)。
- 处理重启导致的重复 saga 执行:为每个步骤动作加幂等键,防止 orchestrator 重启后重放事件并重复执行已完成步骤。
- 处理 choreography saga 丢事件:使用持久化消息 broker(Kafka 带副本、RabbitMQ 带持久化),并把当前 saga 状态存入专用 saga_log 表以便从最后已知良好步骤重放。
- 处理慢但有效步骤被超时误杀:按步骤类型配置超时(如 create_shipment 峰值可达 15 分钟,不要用 5 分钟全局超时),参考 TimeoutSagaOrchestrator 与 STEP_TIMEOUTS 字典模式。
- 处理补偿顺序与执行顺序不一致:确保 _compensate() 从 current_step - 1 递减到 0,并添加在每个步骤索引故意失败的集成测试以验证回滚顺序。
适用边界 · 注意事项
- 需要强原子性且 2PC 可用、延迟可接受的场景(Saga 是异步补偿,非真正原子)。
- 无法为每个步骤编写幂等补偿逻辑、也无法保证补偿始终发布结果事件的系统。
- 没有持久化消息基础设施、无法容忍最终一致与长流程(分钟到小时)的场景。