Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 53 — BPMN cho microservices orchestration

Business Process Mapping and BPMN Bài 53/60

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn vừa chuyển một hệ thống monolith cũ kỹ sang kiến trúc microservices. Trên giấy tờ, mọi thứ thật đẹp: mỗi service nhỏ gọn, độc lập, dễ deploy, dễ scale. Nhưng rồi một ngày, sếp hỏi bạn: "Quy trình duyệt khoản vay đang chạy đến đâu rồi? Tại sao đơn của khách hàng X bị treo 3 ngày?" — và bạn ngớ người ra. Bởi vì cái quy trình "duyệt khoản vay" đó không nằm ở đâu cả. Nó bị xé nhỏ thành mười mảnh, mỗi mảnh nằm trong một service khác nhau, giao tiếp với nhau qua một mớ message và REST call rải rác khắp nơi. Không ai nhìn thấy bức tranh toàn cảnh.

Đây chính là nghịch lý lớn nhất của microservices: bạn tối ưu được tính độc lập của từng service, nhưng lại đánh mất khả năng nhìn và kiểm soát business process xuyên suốt nhiều service. Một nghiệp vụ kinh doanh thực tế — đặt hàng, thanh toán, giao hàng, hoàn tiền — hiếm khi gói gọn trong một service. Nó là một chuỗi các bước cần được điều phối (coordination).

Bài học này dạy bạn cách dùng BPMN — thứ bạn đã học suốt từ Bài 1 đến Bài 52 — như một công cụ điều phối thật sự trong thế giới microservices, chứ không chỉ là sơ đồ vẽ để treo tường. Bạn sẽ hiểu hai mô hình điều phối nền tảng (orchestration và choreography), khi nào dùng cái nào, và cách một process engine biến sơ đồ BPMN thành "nhạc trưởng" thật sự điều khiển các service. Đây là kỹ năng phân biệt giữa một Business Process Analyst chỉ biết vẽ và một người hiểu cách process sống trong production.

Khái niệm cốt lõi

Vấn đề gốc: business process không thuộc về service nào

Trong microservices, mỗi service "sở hữu" dữ liệu và logic của riêng nó: order-service, payment-service, inventory-service, shipping-service. Nhưng quy trình "Hoàn tất một đơn hàng" cần cả bốn service phối hợp theo đúng thứ tự, đúng điều kiện, và xử lý được khi một bước thất bại.

Câu hỏi đặt ra: ai chịu trách nhiệm điều phối chuỗi này? Có hai trường phái trả lời, và đây là hai pattern bạn bắt buộc phải nắm.

Pattern 1 — Orchestration (điều phối tập trung)

Trong orchestration, có một thành phần trung tâm — gọi là orchestrator — đóng vai trò "nhạc trưởng". Nó nắm giữ toàn bộ logic của quy trình: bước nào trước, bước nào sau, rẽ nhánh khi nào, làm gì khi lỗi. Orchestrator gọi từng service theo trình tự và chờ kết quả trả về để quyết định bước tiếp theo.

Đây chính là nơi BPMN tỏa sáng. Một sơ đồ BPMN với các Service Task, Gateway và Event được nạp vào một process engine (như Camunda, bạn sẽ học sâu ở Bài 31) và engine đó trở thành orchestrator. Token chạy qua sơ đồ (nhớ lại token semantics ở Bài 26): khi token đến một Service Task "Charge Payment", engine gọi payment-service; khi service trả kết quả, token đi tiếp đến Exclusive Gateway để quyết định "thanh toán thành công hay thất bại".

Ưu điểm: logic quy trình nằm gọn ở một chỗ, nhìn thấy được, sửa được, audit được. Nhược điểm: orchestrator trở thành điểm phụ thuộc trung tâm — nếu thiết kế kém, nó dễ thành "God service" biết quá nhiều và là single point of failure.

Pattern 2 — Choreography (điều phối phân tán)

Trong choreography, không có nhạc trưởng. Mỗi service tự lắng nghe các sự kiện (event) và tự quyết định phản ứng, rồi phát ra event mới cho service khác nghe. Giống như một điệu nhảy tập thể: không ai chỉ huy, nhưng mỗi vũ công biết khi nhạc đến đoạn nào thì mình làm gì.

Ví dụ: order-service phát event OrderPlacedpayment-service nghe được, xử lý thanh toán, phát PaymentConfirmedinventory-service nghe, trừ kho, phát StockReservedshipping-service nghe và giao hàng. Không service nào "ra lệnh" cho service khác; chúng chỉ phản ứng với event.

BPMN biểu diễn choreography qua Collaboration diagram với nhiều Pool (mỗi Pool là một service/participant) và Message Flow nối giữa chúng (nhớ lại Bài 18 và Bài 24). Ở đây BPMN đóng vai trò mô tả và truyền đạt, chứ không trực tiếp thực thi như trong orchestration.

Ưu điểm: các service thực sự độc lập, nới lỏng coupling, dễ scale từng phần. Nhược điểm: không ai nhìn thấy toàn bộ quy trình; rất khó debug ("đơn hàng này treo ở đâu?"), khó thay đổi logic xuyên suốt, và dễ rơi vào tình trạng "không ai chịu trách nhiệm về cái tổng thể".

So sánh nhanh để chọn

Tiêu chíOrchestrationChoreography
Logic quy trìnhTập trung ở enginePhân tán trong từng service
Khả năng quan sát (visibility)Cao — thấy toàn bộThấp — phải ghép từ log
CouplingTrung bình (qua orchestrator)Thấp
Phù hợp khiQuy trình phức tạp, nhiều rẽ nhánh, cần auditLuồng đơn giản, event-driven, cần scale cao

Saga pattern và bù trừ (compensation)

Một điểm cốt lõi khi điều phối xuyên service: không có transaction toàn cục như trong một database đơn lẻ. Nếu bước 4 thất bại, bạn không thể "rollback" bước 1, 2, 3 một cách tự động. Giải pháp là Saga pattern: mỗi bước có một hành động bù trừ (compensating action). Đã charge tiền nhưng giao hàng thất bại? Phải hoàn tiền. Đã trừ kho nhưng đơn bị hủy? Phải cộng kho lại.

Đây chính xác là nơi Compensation trong BPMN (Bài 23) gặp microservices. Trong một process engine, bạn gắn Compensation Boundary Event vào từng Service Task; khi process thất bại ở giữa chừng, engine tự động chạy các compensation handler theo thứ tự ngược lại. BPMN + Saga là một cặp đôi cực kỳ mạnh để xử lý "transaction phân tán" một cách có kỷ luật.

Tình huống thực tế

Ví dụ 1 — Sàn TMĐT "ShopFast" (giả định, bối cảnh Việt Nam): chọn Orchestration

ShopFast là một sàn thương mại điện tử vừa tại TP.HCM, xử lý khoảng 40.000 đơn/ngày. Khi tách monolith ra microservices, nhóm kỹ thuật ban đầu chọn choreography cho luồng đặt hàng vì nghe "hiện đại và phân tán". Sau 3 tháng, đội vận hành phát điên: mỗi khi khách khiếu nại "đơn của tôi đâu rồi?", kỹ sư phải mò qua log của 6 service khác nhau, mất trung bình 45 phút mỗi ca.

Họ chuyển luồng đặt hàng sang orchestration dùng một process engine với sơ đồ BPMN: Start Event "Đơn được tạo" → Service Task "Kiểm tra tồn kho" → Exclusive Gateway "Còn hàng?" → Service Task "Charge thanh toán" (gắn Compensation "Hoàn tiền") → Service Task "Tạo lệnh giao hàng" → End Event. Mỗi Service Task gọi một microservice tương ứng.

Bài học rút ra: Sau khi chuyển, thời gian tra cứu trạng thái một đơn giảm từ 45 phút xuống còn dưới 1 phút — đội vận hành chỉ cần mở Cockpit của engine và thấy ngay token đang dừng ở Service Task nào, tại sao. Với quy trình nghiệp vụ có nhiều rẽ nhánh và cần audit (đặc biệt liên quan tiền bạc), orchestration thắng thế nhờ khả năng quan sát.

Ví dụ 2 — Grab Đông Nam Á (giả định hợp lý dựa trên kiến trúc event-driven phổ biến): Choreography cho thông báo

Một nền tảng gọi xe quy mô khu vực như Grab xử lý hàng triệu sự kiện mỗi phút. Với luồng "thông báo sau chuyến đi" — gửi biên lai, cộng điểm thưởng, mời đánh giá, cập nhật phân tích — họ chọn choreography. Khi service chuyến đi phát event TripCompleted, hàng loạt service độc lập cùng nghe: receipt-service gửi biên lai, loyalty-service cộng điểm, rating-service đẩy yêu cầu đánh giá, analytics-service ghi nhận dữ liệu.

Không có orchestrator nào ở đây. Nếu mai họ thêm một service mới (ví dụ carbon-service tính lượng khí thải để gắn nhãn "chuyến đi xanh"), họ chỉ cần cho nó subscribe vào event TripCompletedkhông phải sửa bất kỳ service nào khác. Họ vẽ Collaboration diagram BPMN với nhiều Pool và Message Flow để tài liệu hóa luồng này cho cả team đọc.

Bài học rút ra: Khi các phản ứng độc lập với nhau, không cần thứ tự nghiêm ngặt, và bạn muốn dễ dàng thêm/bớt service — choreography là lựa chọn đúng. Khả năng "cắm thêm service mới mà không đụng vào cái cũ" là siêu năng lực của mô hình này.

Ví dụ 3 — Ngân hàng số "VBank" (giả định): kết hợp cả hai

VBank xây dựng quy trình mở tài khoản trực tuyến (eKYC). Họ nhận ra không có lựa chọn "tất cả hoặc không gì cả". Họ dùng orchestration cho phần lõi cần kiểm soát chặt: BPMN process điều phối các bước xác thực CMND, đối chiếu khuôn mặt, kiểm tra blacklist, tạo tài khoản — vì luồng này có nhiều Gateway quyết định (đậu/rớt eKYC), cần audit cho cơ quan quản lý, và phải có compensation rõ ràng nếu fail giữa chừng.

Nhưng sau khi tài khoản tạo xong, họ chuyển sang choreography: process engine phát một event AccountOpened, rồi các service phụ trợ (gửi welcome email, kích hoạt thẻ ảo, tặng voucher, đẩy CRM) tự nghe và xử lý độc lập.

Bài học rút ra: Trong thực tế, kiến trúc trưởng giỏi không chọn phe. Họ dùng orchestration cho phần "xương sống nghiệp vụ" cần kiểm soát, và choreography cho phần "vệ tinh" cần linh hoạt. Ranh giới thường là: cái gì ảnh hưởng trực tiếp đến kết quả nghiệp vụ thì orchestrate; cái gì là tác dụng phụ (side-effect) thì choreograph.

Hướng dẫn từng bước

Đây là quy trình thực tế để thiết kế điều phối cho một business process xuyên microservices:

  • Vẽ As-Is bằng ngôn ngữ nghiệp vụ trước. Đừng nghĩ đến service vội. Vẽ một process map BPMN mô tả quy trình nghiệp vụ thuần túy (như Bài 9 đã dạy): đặt hàng → thanh toán → giao hàng. Đây là bức tranh mà người kinh doanh hiểu được.
  • Ánh xạ mỗi activity sang service owner. Với từng Task trong sơ đồ, xác định service nào sẽ thực hiện nó. Nếu một Task cần đến dữ liệu của hai service, đó là dấu hiệu ranh giới service của bạn có vấn đề — xem lại.
  • Quyết định orchestration hay choreography cho từng luồng. Hỏi ba câu: Luồng này có cần audit và quan sát chặt không? Có nhiều rẽ nhánh quyết định không? Các bước có cần đúng thứ tự không? Nếu phần lớn câu trả lời là "có" → orchestration. Nếu là các phản ứng độc lập, không thứ tự → choreography.
  • Với orchestration: chuyển sơ đồ thành executable BPMN. Thay các Task thường bằng Service Task, mỗi cái trỏ tới một service implementation. Thêm Gateway cho quyết định, Error Boundary Event (Bài 22) cho xử lý lỗi, và Compensation (Bài 23) cho Saga rollback.
  • Định nghĩa compensation cho mỗi bước có side-effect không thể tự rollback. Charge tiền → compensation là hoàn tiền. Trừ kho → compensation là cộng kho. Gửi email → thường không cần compensation (đã gửi là gửi rồi). Liệt kê rõ ràng từng cái.
  • Thiết kế cơ chế retry và timeout. Service được gọi có thể tạm thời không phản hồi. Dùng Timer Boundary Event (Bài 42) để escalate khi quá thời gian, và cấu hình retry với backoff. Đừng để token kẹt vô hạn.
  • Với choreography: thiết kế hợp đồng event (event contract). Định nghĩa rõ tên event, schema payload, và service nào phát/nghe. Vẽ Collaboration diagram để tài liệu hóa. Đặt event vào một message broker (Kafka, RabbitMQ).
  • Bổ sung khả năng quan sát. Dù chọn pattern nào, hãy gắn một correlation ID xuyên suốt mọi bước để có thể truy vết một process instance qua các service — đây là điều choreography hay thiếu nhất.

Lỗi thường gặp & mẹo

Lỗi 1 — Biến orchestrator thành "God service". Nhiều team nhồi mọi logic nghiệp vụ vào orchestrator, kể cả những thứ thuộc về service. Kết quả: orchestrator biết quá nhiều, sửa service nào cũng phải sửa nó. Mẹo: orchestrator chỉ nên biết "trình tự và quyết định", còn logic nghiệp vụ chi tiết phải nằm trong service. Service Task chỉ gọi và nhận kết quả, không nhúng business rule của service vào sơ đồ.

Lỗi 2 — Dùng choreography cho luồng cần kiểm soát chặt. Đây là sai lầm "chạy theo mốt". Choreography làm luồng tiền bạc, pháp lý trở thành hộp đen không ai debug nổi. Mẹo: hỏi "khi có sự cố lúc 2 giờ sáng, tôi sẽ debug thế nào?" — nếu câu trả lời khiến bạn rùng mình, chọn orchestration.

Lỗi 3 — Quên Saga/compensation, giả định có distributed transaction. Microservices KHÔNG có transaction toàn cục như một database. Tin rằng "nếu bước cuối fail thì mọi thứ tự rollback" là ảo tưởng tai hại dẫn đến dữ liệu rác (đã trừ tiền nhưng không giao hàng). Mẹo: mỗi bước có side-effect bắt buộc phải có compensation được định nghĩa rõ ràng từ ngày đầu.

Lỗi 4 — Service Task gọi đồng bộ và chờ quá lâu. Để orchestrator gọi synchronous một service chậm sẽ khóa luồng và làm sập engine khi tải cao. Mẹo: với các tác vụ dài, dùng pattern bất đồng bộ — engine gửi yêu cầu rồi chờ message trả về (Receive Task / Message Event), thay vì block.

Lỗi 5 — Không có correlation ID. Không thể truy vết một instance qua nhiều service là cơn ác mộng vận hành. Mẹo: truyền correlation ID trong mọi message/header ngay từ kiến trúc ban đầu, đừng để nó là "việc tính sau".

Mẹo vàng: Hãy bắt đầu với orchestration cho phần lõi. Nó dễ hiểu, dễ debug, dễ thay đổi hơn cho người mới. Chỉ chuyển sang choreography khi bạn có lý do scaling cụ thể và đội ngũ đủ trưởng thành về quan sát hệ thống.

Bài tập thực hành

Bài 1 — Phân loại pattern. Cho 4 luồng sau, hãy quyết định orchestration hay choreography và giải thích: (a) Quy trình phê duyệt khoản vay 5 bước có thẩm định; (b) Gửi thông báo khuyến mãi sau khi khách mua hàng; (c) Quy trình hoàn tiền cần audit; (d) Cập nhật bộ nhớ đệm khi sản phẩm đổi giá.

Bài 2 — Vẽ orchestration. Vẽ một executable BPMN cho quy trình "đặt phòng khách sạn" gồm: kiểm tra phòng trống → giữ phòng → thanh toán → xác nhận. Đánh dấu Service Task nào gọi service nào, và thêm Compensation cho ít nhất hai bước.

Bài 3 — Thiết kế Saga. Với quy trình ở Bài 2, liệt kê bảng compensation: với mỗi bước, hành động bù trừ là gì? Bước nào không cần compensation và tại sao?

Bài 4 — Vẽ choreography. Cho luồng "đơn hàng hoàn tất" với các service receipt, loyalty, analytics. Vẽ Collaboration diagram BPMN với các Pool và Message Flow, bắt đầu từ event OrderCompleted.

Bài 5 — Tình huống mở. Hệ thống của bạn dùng choreography và một đơn hàng bị "treo": tiền đã trừ nhưng kho chưa giảm. Hãy mô tả bạn sẽ debug như thế nào, và đề xuất một thay đổi kiến trúc để tránh lặp lại.

Tóm tắt

Microservices giải quyết vấn đề độc lập của từng service nhưng tạo ra một vấn đề mới: business process bị xé nhỏ và không ai nhìn thấy bức tranh tổng thể. BPMN là công cụ mạnh để giải quyết chuyện này thông qua hai pattern điều phối nền tảng.

Orchestration dùng một orchestrator trung tâm — thường là process engine chạy executable BPMN — đóng vai nhạc trưởng gọi từng service theo trình tự. Nó cho khả năng quan sát và kiểm soát cao, phù hợp với quy trình phức tạp, nhiều rẽ nhánh, cần audit. Choreography không có nhạc trưởng; các service tự nghe event và phản ứng, cho coupling thấp và dễ mở rộng, phù hợp với các phản ứng độc lập, event-driven.

Trong thực tế, kiến trúc tốt thường kết hợp cả hai: orchestrate phần xương sống nghiệp vụ cần kiểm soát, choreograph phần vệ tinh cần linh hoạt. Và dù chọn pattern nào, đừng bao giờ quên rằng microservices không có distributed transaction — bạn phải dùng Saga pattern với compensation (Compensation trong BPMN) để xử lý thất bại giữa chừng một cách có kỷ luật. Cùng với correlation ID xuyên suốt để truy vết, đó là bộ ba giúp business process của bạn vừa phân tán vừa kiểm soát được.