使用 RabbitMQ 实现 Saga 模式
使用 RabbitMQ 实现 Saga 模式,以管理长时间运行的分布式事务。可靠地编排跨多个微服务的复杂工作流。
使用 RabbitMQ 实现 Saga 模式 是 CoddyKit 上的免费 RabbitMQ Messaging & Async Systems 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 RabbitMQ Messaging & Async Systems 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 RabbitMQ Messaging & Async Systems 课程共包含 4 节课。
本课时的部分内容尚未翻译,以英文显示。
Distributed Transactions Unveiled
In microservices, a single business operation often spans multiple services. For example, placing an order might involve an Order Service, Inventory Service, and Payment Service.
A distributed transaction ensures that all these separate operations either succeed together or fail together, maintaining data consistency across your system.
Beyond Two-Phase Commit
Traditional database transactions often use a Two-Phase Commit (2PC) protocol to ensure atomicity. However, 2PC isn't ideal for microservices because:
- It creates tight coupling between services.
- It can lead to long-held locks, impacting availability.
- It's complex to implement and manage across different technologies.
We need a more flexible approach for distributed systems.
Introducing the Saga Pattern
The Saga pattern is a way to manage distributed transactions. Instead of a single atomic transaction, a saga is a sequence of local transactions, each updating its own service's database.
- Each local transaction publishes an event upon completion.
- These events trigger the next step in the saga.
- If a step fails, compensating transactions are used to undo previous successful steps.
The goal is eventual consistency.
Two Saga Flavors
There are two main ways to implement a Saga:
- Orchestration: A central "Saga Orchestrator" service manages and directs the workflow, telling each participant what to do next.
- Choreography: Each service produces and listens to events, deciding its own next action without a central coordinator.
For this lesson, we'll focus on the Orchestration approach, which often pairs well with message brokers like RabbitMQ.
The Brain of the Saga
The Saga Orchestrator is a dedicated service responsible for:
- Receiving the initial command (e.g., "Create Order").
- Sending commands to saga participants (microservices).
- Listening for events from participants.
- Maintaining the saga's state.
- Deciding the next step or initiating compensating transactions if a step fails.
RabbitMQ is perfect for the orchestrator to send commands and receive events.
Participants & Local Transactions
A Saga Participant is a microservice involved in the distributed transaction. When it receives a command from the orchestrator, it:
- Performs its own local ACID transaction.
- Updates its database.
- Publishes an event (e.g., "OrderCreatedEvent", "StockReservedEvent") indicating success or failure.
These events are crucial for the orchestrator to continue the saga.
Undo Actions: Compensation
What happens if a step in the saga fails? This is where compensating transactions come in. They are operations designed to reverse the effects of previously completed local transactions.
For example, if a "Process Payment" step fails, a compensating transaction for "Reserve Stock" might be to release the reserved items back into inventory.
This ensures the system returns to a consistent state, even if not fully rolled back.
Orchestrator Kicks Off
Let's imagine an order creation saga. The orchestrator receives a request and sends a command to the first participant (e.g., "Order Service"). Here's a simplified Java example:
public class OrderSagaOrchestrator {
public void startOrderCreationSaga(String orderId, String userId, double amount) {
System.out.println("Orchestrator: Starting saga for Order " + orderId);
// Simulate sending a message to Order Service
String command = "CreateOrderCommand { orderId: " + orderId + ", userId: " + userId + ", amount: " + amount + " }";
System.out.println("Orchestrator: Sending command to Order Service: " + command);
// In a real app, this would be a RabbitMQ message send
}
public static void main(String[] args) {
OrderSagaOrchestrator orchestrator = new OrderSagaOrchestrator();
orchestrator.startOrderCreationSaga("ORD-001", "user123", 99.99);
}
}Participant Responds
Now, let's look at the "Order Service" (a participant) receiving the command. It processes the order locally and then publishes an event.
public class OrderServiceParticipant {
public void handleCreateOrderCommand(String commandMessage) {
System.out.println("OrderService: Received command: " + commandMessage);
// Simulate local transaction (e.g., save order to DB)
String orderId = "ORD-001"; // Extract from commandMessage in real app
System.out.println("OrderService: Successfully created local order " + orderId);
// Simulate publishing an event back to the orchestrator
String event = "OrderCreatedEvent { orderId: " + orderId + ", status: 'PENDING_PAYMENT' }";
System.out.println("OrderService: Publishing event: " + event);
// In a real app, this would be a RabbitMQ message publish
}
public static void main(String[] args) {
OrderServiceParticipant participant = new OrderServiceParticipant();
participant.handleCreateOrderCommand("CreateOrderCommand { orderId: ORD-001, userId: user123, amount: 99.99 }");
}
}Orchestrator Continues Flow
The orchestrator listens for events like OrderCreatedEvent. Upon receiving it, it updates the saga's state and sends the next command, perhaps to an "Inventory Service" to reserve stock.
public class OrderSagaOrchestratorContinued {
public void handleOrderCreatedEvent(String eventMessage) {
System.out.println("Orchestrator: Received event: " + eventMessage);
String orderId = "ORD-001"; // Extract from eventMessage
// Update saga state (e.g., mark order as 'OrderCreated')
// Decide next step: send command to Inventory Service
String command = "ReserveStockCommand { orderId: " + orderId + ", productId: 'PROD-A', quantity: 2 }";
System.out.println("Orchestrator: Sending command to Inventory Service: " + command);
}
public static void main(String[] args) {
OrderSagaOrchestratorContinued orchestrator = new OrderSagaOrchestratorContinued();
orchestrator.handleOrderCreatedEvent("OrderCreatedEvent { orderId: ORD-001, status: 'PENDING_PAYMENT' }");
}
}Saga Essentials Check
Which of the following are key components or characteristics of the Saga Orchestration pattern?
Saga for Reliability
The Saga pattern is a powerful way to manage complex, long-running distributed transactions in microservice architectures.
- It enables eventual consistency without tight coupling.
- It uses local transactions and compensating transactions for resilience.
- RabbitMQ provides the perfect backbone for the orchestrator and participants to communicate reliably through commands and events.
While adding complexity, Sagas are essential for building robust distributed systems.
常见问题解答
「使用 RabbitMQ 实现 Saga 模式」课时是免费的吗?
是的 — 「使用 RabbitMQ 实现 Saga 模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 RabbitMQ Messaging & Async Systems 课程的其余内容,请升级到 CoddyKit PRO。 RabbitMQ Messaging & Async Systems 课程共包含 4 节课。
「使用 RabbitMQ 实现 Saga 模式」这节课中我会学到什么?
使用 RabbitMQ 实现 Saga 模式,以管理长时间运行的分布式事务。可靠地编排跨多个微服务的复杂工作流。 你通过在浏览器中直接运行的动手代码来练习 RabbitMQ Messaging & Async Systems,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 RabbitMQ Messaging & Async Systems 需要有经验吗?
无需任何先前经验。CoddyKit 上的 RabbitMQ Messaging & Async Systems 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「使用 RabbitMQ 实现 Saga 模式」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 RabbitMQ Messaging & Async Systems 课中编写并运行代码吗?
能。每节 RabbitMQ Messaging & Async Systems 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 消息处理中的幂等性
- 使用 RabbitMQ 实现 Saga 模式
- 命令查询职责分离(CQRS)
- 可靠发布的发件箱模式