E7 - 跨服务工作流:Choreography + Orchestration + Saga
跨多个微服务的业务流程怎么组织——3 大决策(Choreography / Orchestration)+ Saga 作为分布式事务的替代。
一句话
Choreography = 事件驱动 + 无中心协调;Orchestration = 中央协调器显式控制;Saga = 多步 + 补偿——选择取决于工作流复杂度 + 修改频率 + 团队规模。
这本书在这一层说了什么
本层基于 EDM Ch 8 完整精读(29KB / 4443 词)。
Bellemare Ch 8 关键洞察:
"Microservices, by their very definition, operate on only a small portion of the overall business workflow of an organization... Most of what we've looked at so far has been how single microservices operate under the hood. Now we're going to take a look at how multiple microservices can work together to fulfill larger business workflows."
核心论点 5 个:
- Choreography Pattern — 事件驱动协调(无中心)
- Orchestration Pattern — 中央协调器
- Choreography vs Orchestration 决策矩阵
- Saga 实现
- 工作流监控(关联 ID + 分布式追踪)
是什么
1. Choreography Pattern(编排)
Bellemare 关键定义:
"The term choreographed architectures (also known as reactive architectures) commonly refers to highly decoupled microservice architectures. Microservices react to their input events as they arrive, without any blocking or waiting."
特征:
特征:
- 服务间无直接调用
- 通过事件流通信
- 每个服务独立反应
- 工作流是"涌现行为"Bellemare 关键洞察:
"The relationships between the microservices define the workflow of a choreographed architecture... This choreographed workflow is a form of emergent behavior, where it is not just the individual microservices that dictate the workflow, but the relationships between them as well."
形象比喻:舞蹈编排——每个人按音乐跳,没人指挥,整体协调是"涌现"。
优点:
- 松耦合
- 易添加/删除服务
- 故障隔离
缺点:
- 工作流难追踪
- 中间插入步骤难
- 顺序修改困难
2. Orchestration Pattern(协调)
Bellemare 关键定义:
"In the orchestration pattern a central microservice, the orchestrator, issues commands to and awaits responses from subordinate worker microservices. Orchestration can be thought of much like a musical orchestra, where a single conductor commands the musicians during the performance."
特征:
特征:
- 中央 Orchestrator 服务
- 显式调用其他服务
- 显式工作流逻辑
- 显式补偿逻辑Bellemare 关键提醒:
"If a payment microservice attempts to fulfill payment three times before failing, it must make those three attempts internal to the payment microservice. It does not make one attempt and notify the orchestrator that it failed and wait to be told to try again or not. The orchestrator should have no say about how payments are processed, including how many attempts to make, as that is part of the bounded context of the payment microservice."
关键洞察:Orchestrator 只管工作流,不管业务细节——重试逻辑在 Worker 内部。
Bellemare 关键论断:
"Ensure the orchestrator's bounded context is limited strictly to workflow logic and that it contains minimal business fulfillment logic."
形象比喻:交响乐指挥——一个指挥控制每个乐手。
优点:
- 工作流清晰可见
- 易于修改
- 易于追踪
缺点:
- 中央协调器是单点
- 紧耦合
- 难演化
3. Choreography vs Orchestration 决策矩阵
| 维度 | Choreography | Orchestration |
|---|---|---|
| 工作流复杂度 | 低(≤5 步) | 高(≥5 步) |
| 修改频率 | 低 | 高 |
| 团队数量 | 多 | 少 |
| 故障容忍 | 高 | 中 |
| 可观测性 | 低(需分布式追踪) | 高(中央可见) |
| 演化灵活度 | 高 | 低 |
Bellemare 关键洞察:
"Choreography is desirable in the majority of interteam communications, as it allows for loosely coupled systems and reduces coordination requirements."
判断:
- 工作流简单 + 多团队 + 高演化 → Choreography
- 工作流复杂 + 修改频繁 + 需可观测 → Orchestration
4. Saga 模式
Bellemare Ch 8 详细讨论:
问题:跨服务事务
方案:Saga = 多步 + 补偿
例:下单
Step 1: 创建订单
Step 2: 扣库存
Step 3: 扣款
Step 4: 发货
任一步失败:
- 补偿已完成的步骤
- 整体回滚两种实现:
- Orchestrated Saga:中央 Saga Manager 显式调用 + 补偿
- Choreographed Saga:事件驱动,每步完成后触发下一步,失败发补偿事件
5. 工作流监控
难点:
- 工作流跨多服务
- 无统一堆栈
方法:
关联 ID(Correlation ID):
- 每个工作流启动时生成唯一 ID
- 写入所有事件
- 消费方记录
- 故障时按 ID 搜索
分布式追踪(Distributed Tracing):
- OpenTelemetry / Jaeger
- 跨服务调用追踪
状态机建模:
- 工作流状态 = 显式状态机
- 状态转换 = 事件为什么
为什么 Choreography 在简单场景更优?
反例(Orchestration 简单场景):
- 3 步流程 + 5 个团队
- 中央协调器是所有团队的瓶颈
- 改一步全部团队等
Choreography:
- 每个团队改自己服务 + 发新事件
- 不需要中央协调
- 改一步只需该团队决定
根因:协调成本随团队数量线性增长(Orchestration)或近零增长(Choreography)。
为什么 Orchestration 在复杂场景更优?
反例(Choreography 复杂场景):
- 10 步流程 + 多种分支 + 多种补偿
- 工作流散布在 10 个服务
- 任何修改都要跨服务追踪
Orchestration:
- 中央协调器是"工作流的事实源"
- 所有逻辑集中可读
根因:认知负载随步骤数指数增长(Choreography)或线性增长(Orchestration)。
为什么 Orchestrator 不管重试?
Bellemare 关键洞察:
"If a payment microservice attempts to fulfill payment three times before failing, it must make those three attempts internal to the payment microservice... The orchestrator should have no say about how payments are processed, including how many attempts to make, as that is part of the bounded context of the payment microservice."
根因:
- 重试策略 = 业务细节
- 业务细节 = 属于 Worker BC
- Orchestrator 只关心"成功 / 失败"二元结果
为什么 Saga 是分布式事务的唯一方案?
理论:CAP 定理——分布式系统不能同时保证 C + A + P。
- 强一致(2PC / XA)→ 牺牲可用性
- 最终一致(Saga)→ 牺牲强一致性
判断:
- 业务能容忍"最终一致"(秒级延迟)→ Saga
- 必须"强一致"(金融核心)→ 2PC + 同步阻塞
怎么做
Step 1:判断工作流复杂度
判断标准:
- 步骤数 ≤ 5 + 分支 ≤ 2 + 团队 ≥ 3 → Choreography
- 步骤数 > 5 或分支 > 2 或团队 ≤ 2 → Orchestration
- 不确定 → 先 Choreography(演化时再改 Orchestration)Step 2:实施 Choreography
工作流:客户下单 → 扣库存 → 扣款 → 发货
事件链:
OrderCreated 事件(订单服务发布)
↓ 库存服务订阅
InventoryReserved 事件(库存服务发布)
↓ 支付服务订阅
PaymentProcessed 事件(支付服务发布)
↓ 物流服务订阅
ShipmentScheduled 事件(物流服务发布)每个服务:
- 订阅上游事件
- 处理业务逻辑
- 发布下游事件
- 失败时发布"补偿事件"
Step 3:实施 Orchestrated Saga
# 伪代码:中央 Saga Manager
class OrderSaga:
def execute(self, order_request):
try:
order = self.order_service.create(order_request)
inventory = self.inventory_service.reserve(order)
payment = self.payment_service.charge(order)
shipment = self.shipment_service.schedule(order)
return order
except InventoryReservationFailed:
self.order_service.cancel(order, reason="inventory")
except PaymentFailed:
self.inventory_service.release(inventory)
self.order_service.cancel(order, reason="payment")
except ShipmentSchedulingFailed:
self.payment_service.refund(payment)
self.inventory_service.release(inventory)
self.order_service.cancel(order, reason="shipment")Step 4:实施关联 ID + 分布式追踪
# 每个事件携带关联 ID
event = {
"type": "OrderCreated",
"correlation_id": "saga-uuid-1234",
"data": {...}
}
# OpenTelemetry 自动追踪
from opentelemetry import trace
tracer = trace.get_tracer(__name__)
with tracer.start_as_current_span("process_order") as span:
span.set_attribute("correlation_id", correlation_id)
# 处理逻辑Step 5:Saga 测试策略
单元测试:
- 每个服务的"成功路径" + "失败路径"(含补偿)
集成测试:
- 完整 Saga 成功路径(所有服务 mock)
- 失败场景(某服务 mock 失败 → 验证补偿被调用)
契约测试:
- Producer 发布的事件符合 Schema(参考 E3)
- Consumer 订阅的事件符合 Schema
端到端测试:
- 启动所有服务 + 真实事件流
- 触发真实业务场景
- 验证最终状态一致什么时候用 / 什么时候不用
用 Choreography 的 2 大场景
| 场景 | 关键判断 |
|---|---|
| 简单工作流(≤5 步)+ 多团队 | Choreography 协调成本低 |
| 业务频繁演化(增加/删除步骤) | Choreography 加服务不改全局 |
用 Orchestration 的 2 大场景
| 场景 | 关键判断 |
|---|---|
| 复杂工作流(≥5 步)+ 频繁修改 | Orchestration 集中可读 |
| 需要强可观测性(合规/审计) | Orchestrator 是工作流的事实源 |
不用的 2 大场景
| 场景 | 原因 | 替代 |
|---|---|---|
| 单体足够 | 跨服务协调成本 0 | 单体事务 |
| 强一致事务必要 | Saga 最终一致不满足 | 2PC / 同步阻塞 |
看不见的地方
失效模式 1:Choreography 协调失控
症状:业务流程偶发失败 → 难以定位"哪一步没执行" → 多人排查数日。
根因:Choreography 无中央协调器 → 工作流散布在各服务。
修复:每个工作流实例必须有"状态机"记录(即使 Choreography)+ 关联 ID 全链路追踪。
失效模式 2:Saga 补偿不完整
症状:业务失败 → 部分补偿执行 → 数据漂移。
根因:补偿逻辑遗漏边界情况(如某服务在补偿时已宕机)。
修复:补偿必须幂等 + 重试 + 死信队列 + 定期对账。
失效模式 3:Orchestrator 单点故障
症状:Orchestrator 服务挂了 → 所有工作流阻塞 → 业务停滞。
根因:Orchestrator 是单点 → 无高可用。
修复:Orchestrator 状态持久化 + 故障转移 + 重启从持久状态恢复。
失效模式 4:关联 ID 丢失
症状:跨服务追踪断裂 → 部分事件有关联 ID,部分没有。
根因:手动传递关联 ID 容易遗漏。
修复:用框架自动注入关联 ID(如 OpenTelemetry baggage)。
失效模式 5:Orchestrator 管太多业务
症状:Orchestrator 服务包含业务逻辑 → 工作流变复杂 → 重试 / 补偿逻辑混乱。
根因:违反 Bellemare 的"Orchestrator 只管工作流"原则。
修复:业务逻辑下沉到 Worker BC;Orchestrator 只管协调。
失效模式 6:Saga 长时间悬挂
症状:Saga 启动后某步永远不响应 → 资源悬挂。
根因:无超时机制。
修复:每步必须有超时 + 超时触发补偿 + 死信队列。
相关节点
骨架 A — 世界观
| 节点 | 关联 | 解释 |
|---|---|---|
| wonder-04-encounter | 强 | Saga = "照面"的工作流版本——服务通过事件互相照面 |
| wonder-02-emergence-action | 中 | Choreography = "涌现作为"的工程实现——无中心作为 |
| wonder-03-emergence-time | 中 | 关联 ID = "时"的索引——所有事件沿同一时间轴追溯 |
骨架 B — 工程实践
| 节点 | 关联 | 解释 |
|---|---|---|
| value-stream | 强 | Saga = 价值流——价值沿步骤流动,每步成功 = 价值前进 |
| feedback-mechanisms | 强 | 关联 ID + 追踪 = 反馈机制——故障时可追溯整条链路 |
| change-management | 中 | Saga 修改 = 变更管理——每改一步要重新设计补偿 |
| quality-assurance | 中 | Saga 测试 = 质量保障——必须覆盖成功 + 失败 + 补偿路径 |
与 IDDD 对位
| IDDD L8 | EDM E7 |
|---|---|
| BC 集成 | Choreography / Orchestration |
| Saga 模式 | Saga 详细实现 |
| 关联 ID | 关联 ID + 分布式追踪 |
状态
E7 概念递进落地完成(基于原书 ch08 29KB / 4443 词)。
- 5 个核心论点(Choreography / Orchestration / 决策矩阵 / Saga / 监控)
- 5 步怎么做
- 6 个失效模式
- 骨架 A/B + IDDD 完整映射