Thiết kế Workflow cho Microservices — Orchestration vs Choreography

Phong

Mở đầu

Ảnh: Vito Goričan — Pexels

Khi một business operation cần đi qua nhiều microservices khác nhau — ví dụ đặt hàng cần gọi Order Service, Payment Service, Inventory Service, Shipping Service — vấn đề đặt ra là: ai sẽ chịu trách nhiệm điều phối toàn bộ luồng này? Nếu mỗi service tự quyết định bước tiếp theo, làm sao đảm bảo tính nhất quán khi có lỗi xảy ra ở giữa chừng?

Chương 6 của Building Microservices (Sam Newman) dành trọn vẹn cho chủ đề này: thiết kế workflow trong kiến trúc microservices, với hai mô hình điều phối chính là orchestration và choreography, cùng Saga pattern — giải pháp kinh điển cho distributed transactions.

Bài toán cốt lõi: Distributed transaction không có ACID

Ảnh: Kris Møklebust — Pexels

Trong monolithic application, mọi thứ đơn giản: một database transaction bao gồm nhiều bước, nếu bước nào fail thì rollback tất cả. ACID transactions hoạt động hoàn hảo vì mọi thứ nằm trong cùng một process và database.

Khi chuyển sang microservices, mỗi service có database riêng. Không còn "một transaction" xuyên suốt được nữa. Bạn không thể ACID rollback qua nhiều database khác nhau. Bài toán trở thành: làm sao đảm bảo hệ thống luôn ở trạng thái nhất quán, ngay cả khi một service trong chuỗi xử lý fail?

Newman gọi đây là workflow — cách bạn mô hình hoá và điều phối một business process xuyên suốt nhiều service. Và có hai trường phái chính để giải quyết nó.

Orchestration — "Người nhạc trưởng" chỉ huy toàn bộ

Orchestration giống như một dàn nhạc giao hưởng: có một người chỉ huy (orchestrator) đứng ở trung tâm, quyết định ai chơi gì, khi nào, và xử lý khi có nhạc công chơi sai. Trong microservices, orchestrator là một service riêng biệt — gọi đến các service khác theo thứ tự, chờ response, và quyết định bước tiếp theo.

Ví dụ: Một Order Orchestrator service nhận request đặt hàng. Nó gọi Payment Service → chờ "success" → gọi Inventory Service → chờ "reserved" → gọi Shipping Service → response cho client. Nếu Payment fail, nó gọi compensating action để huỷ toàn bộ.

Ưu điểm:

  • Dễ debug và monitoring — mọi logic workflow tập trung ở một chỗ
  • Dễ quản lý state — orchestrator biết chính xác đang ở bước nào
  • Error handling rõ ràng — mọi exception đều có handler tập trung

Nhược điểm:

  • Orchestrator trở thành single point of failure và bottleneck
  • Có nguy cơ tạo ra "smart orchestrator, dumb services" — orchestrator quá nặng, services mất hết business logic
  • Coupling giữa orchestrator và services — nếu thay đổi workflow, phải sửa cả orchestrator

Choreography — "Vũ điệu" tự do không người chỉ huy

Ảnh: Pixabay — Pexels

Choreography thì ngược lại: giống như một nhóm nhảy freestyle, mỗi người tự biết khi nào vào nhịp dựa trên tín hiệu của người khác. Trong microservices, các service giao tiếp qua events — mỗi service publish event khi hoàn thành việc của mình, service khác subscribe và phản hồi tương ứng.

Ví dụ: Order Service tạo đơn hàng và publish OrderCreated event. Payment Service subscribe event đó, xử lý thanh toán, publish PaymentCompleted. Inventory Service nhận event, reserve hàng, publish InventoryReserved. Shipping Service nhận event, tạo vận đơn. Không có ai "gọi" ai cả — mọi thứ diễn ra tự nhiên qua event stream.

Ưu điểm:

  • Loose coupling tối đa — services không biết về nhau, chỉ biết event schema
  • Scalability tốt — không có bottleneck tập trung
  • Resilience cao — nếu một service chết, event vẫn nằm trong queue, service khởi động lại xử lý tiếp

Nhược điểm:

  • Khó debug — workflow phân tán, không có nơi nào thấy toàn bộ luồng
  • Khó quản lý state tổng thể — bạn phải reconstruct từ nhiều event sources
  • Eventual consistency là bắt buộc — không có transaction đồng bộ
  • Có nguy cơ "event spam" — một service publish quá nhiều event, khó follow

Saga Pattern — Compensating Transactions cho Microservices

Cả orchestration và choreography đều có thể dùng Saga pattern — một khái niệm đã có từ những năm 1987 (Hector Garcia-Molina) nhưng cực kỳ phù hợp với microservices. Saga chia một distributed transaction thành nhiều local transaction nhỏ, mỗi local transaction có kèm một compensating transaction — hành động "undo" nếu có lỗi.

Cách hoạt động: Mỗi bước trong Saga đều được thiết kế với 2 mặt: "do" và "compensate". Nếu bước thứ N trong Saga fail, hệ thống chạy compensate cho N-1 bước trước đó. Ví dụ: nếu Inventory Service không reserve được hàng sau khi đã trừ tiền, compensate action là hoàn tiền (refund).

Có hai loại Saga:

  • Choreography-based Saga: Các service giao tiếp qua events, mỗi service tự publish event khi hoàn thành, và tự implement compensating handler cho các event fail từ service khác.
  • Orchestration-based Saga: Một orchestrator quản lý toàn bộ các step, gọi service kế tiếp hoặc gọi compensating action khi cần.

Khi nào dùng cái gì?

Không có câu trả lời tuyệt đối — Newman nhấn mạnh đây là quyết định dựa trên context của từng hệ thống:

  • Orchestration phù hợp khi: Workflow phức tạp, nhiều conditional branching, cần tracking và monitoring chi tiết, team còn non kinh nghiệm với event-driven architecture.
  • Choreography phù hợp khi: Workflow đơn giản, tuyến tính, team đã quen với event-driven, cần scalability cao và loose coupling tối đa.
  • Có thể kết hợp: Dùng orchestration cho những workflow core (đặt hàng, payment) và choreography cho những workflow phụ (notification, logging).

Một điểm Newman nhấn mạnh: tránh tạo ra "distributed god class" — một orchestrator biết quá nhiều về business logic của các service khác. Orchestrator nên chỉ biết về workflow flow, không biết chi tiết implement của từng service.

Key Takeaways

  • Orchestration dùng central coordinator để điều phối workflow — dễ debug nhưng tạo bottleneck và coupling
  • Choreography dùng event-driven communication — loose coupling nhưng khó follow flow và monitoring
  • Saga pattern giải quyết vấn đề distributed transactions bằng compensating transactions — mỗi bước đều có hành động "undo"
  • Không có "one size fits all" — chọn dựa vào độ phức tạp workflow, kinh nghiệm team, và yêu cầu scalability
  • Có thể kết hợp cả hai: orchestration cho business-critical path, choreography cho non-critical path
  • Orchestrator nên thin — chỉ biết về workflow flow, không biết implementation detail của service khác
  • Compensating transactions là phần KHÓ NHẤT của Saga — thiết kế compensate action sai có thể dẫn đến data inconsistency

📋 Phụ lục thuật ngữ

  • Orchestration — mô hình điều phối tập trung, một orchestrator chỉ huy các service theo thứ tự
  • Choreography — mô hình điều phối phân tán, các service giao tiếp qua events, tự phản hồi
  • Saga — pattern chia distributed transaction thành local transactions + compensating transactions để rollback
  • Compensating transaction — hành động undo khi một bước trong Saga fail (VD: hoàn tiền, huỷ đơn)
  • Event-driven architecture — kiến trúc nơi services giao tiếp bằng cách publish/subscribe events thay vì gọi API trực tiếp
  • Orchestrator — service trung tâm quản lý workflow, quyết định thứ tự và xử lý lỗi

Kết

Chương 6 là một trong những chương thực chiến nhất của Building Microservices. Orchestration vs Choreography không phải là cuộc chiến "ai hơn ai" — mà là công cụ để bạn chọn đúng cho từng tình huống. Newman khuyên: hãy bắt đầu với orchestration nếu team chưa quen event-driven, và dần dần chuyển sang choreography cho những workflow ổn định khi team đã sẵn sàng.

Chapter tiếp theo sẽ bàn về cách tích hợp microservices — patterns giao tiếp giữa các service, REST, gRPC, message queues và cả GraphQL. Hẹn gặp lại bạn ở bài sau.