← Về danh sách
Kỹ nghệ & Quản lý phần mềm
#EDA#이벤트기반#중재자토폴로지#브로커토폴로지#MSA#129회
Cập nhật lần cuối · 2026-09-18

Các topology của kiến trúc hướng sự kiện (EDA)

1. Tổng quan

A. Định nghĩa

Kiến trúc hướng sự kiện (Event Driven Architecture, EDA) là một phong cách kiến trúc tổ chức các thành phần xoay quanh việc phát sinh, truyền tải và xử lý các 'sự kiện (event)' biểu thị sự thay đổi trạng thái của hệ thống. Các thành phần phát hành (Publish) và đăng ký (Subscribe) sự kiện, cộng tác với nhau một cách bất đồng bộ (asynchronous) trong trạng thái liên kết lỏng (loose coupling).

Ý tưởng cốt lõi của EDA có thể tóm gọn trong một câu — 'Đừng gọi trực tiếp, hãy thông báo bằng sự kiện (Don't call, notify)'. Trong các hệ thống theo mô hình yêu cầu-phản hồi (request-response) truyền thống, dịch vụ A gọi trực tiếp API của dịch vụ B. Cách này trực quan nhưng phải trả giá là A và B bị ràng buộc chặt chẽ cả về thời gian lẫn không gian. A phải giữ luồng (thread) và chờ cho đến khi B phản hồi (ràng buộc thời gian), đồng thời A phải biết địa chỉ, giao diện và tính sẵn sàng của B (ràng buộc không gian). Hệ quả là khi B chậm đi hoặc gặp sự cố, ảnh hưởng lập tức lan sang A, rồi tiếp tục lan lên dịch vụ cấp trên đã gọi A (lỗi dây chuyền - cascading failure).

EDA thay đổi tận gốc hướng và bản chất của sự ràng buộc này. A chỉ phát hành sự thật "đơn hàng đã được tạo (OrderCreated)" dưới dạng sự kiện, hoàn toàn không biết ai sẽ tiêu thụ sự kiện đó. Dịch vụ thanh toán B, dịch vụ tồn kho C, dịch vụ thông báo D quan tâm đến sự kiện này sẽ tự đăng ký và tự phản ứng. Ngay cả khi thêm một bên tiêu thụ mới (ví dụ: dịch vụ phân tích marketing E), mã nguồn của A cũng không phải sửa một dòng nào. Mối quan hệ trong đó bên sản xuất và bên tiêu thụ không biết nhau (anonymous) chính là bản chất của EDA, và từ đó phát sinh ba lợi ích: khả năng mở rộng, tính linh hoạt và cô lập sự cố (fault isolation). Vì A kết thúc công việc của mình ngay khi phát hành nên độ trễ phản hồi biến mất (tính thời gian thực), và dù một bên tiêu thụ bị sập, sự kiện vẫn nằm lại trong hàng đợi để xử lý sau, nhờ đó sự cố được cô lập.

Khi triển khai EDA trên thực tế, hình thái triển khai sẽ phân nhánh tùy theo ai là người điều phối luồng sự kiện. Nếu giao trách nhiệm điều phối cho một bộ điều phối trung tâm thì đó là topology trung gian (Mediator); nếu để sự kiện tự lưu chuyển qua broker mà không có bộ điều phối thì đó là topology broker (Broker). Việc lựa chọn giữa hai topology này là quyết định thiết kế đầu tiên và quan trọng nhất của EDA.

B. Bối cảnh ra đời và sự cần thiết

EDA gần đây được chú ý trở lại nhờ ba thay đổi mang tính công nghiệp. Thứ nhất là sự phổ biến của kiến trúc microservice (MSA). Khi chia một khối monolith khổng lồ thành hàng chục, hàng trăm dịch vụ độc lập, lưu lượng giao tiếp giữa các dịch vụ tăng vọt; nếu xử lý toàn bộ bằng lời gọi REST đồng bộ, các dịch vụ sẽ đan xen chằng chịt và rơi vào anti-pattern 'monolith phân tán (distributed monolith)'. Giao tiếp bất đồng bộ thông qua sự kiện là lời giải chuẩn mực cho vấn đề này.

Thứ hai là nhu cầu xử lý thời gian thực (real-time processing). Các nghiệp vụ cần phản ứng tức thì với "điều vừa xảy ra ngay lúc này" ngày càng nhiều, như phát hiện giao dịch bất thường trong tài chính, gợi ý thời gian thực, xử lý luồng cảm biến IoT. Phương thức xử lý theo lô (batch) không thể đảm bảo tính tức thời này, và EDA — truyền ngay sự thay đổi trạng thái dưới dạng sự kiện — trở thành lựa chọn tự nhiên. Thứ ba là sự bùng nổ sự kiện từ IoT và thiết bị di động. Trong môi trường hàng triệu thiết bị đổ ra lượng tín hiệu khổng lồ mỗi giây, một xương sống sự kiện (backbone) có khả năng đệm và phân phối cho nhiều bên tiêu thụ là điều bắt buộc. Khi ba xu hướng này giao nhau, EDA — vốn đồng thời mang lại liên kết lỏng, tính bất đồng bộ và khả năng mở rộng — đã trở thành kiến trúc cơ bản của thời đại cloud native.

2. Các thành phần của EDA và luồng xử lý sự kiện

Để hiểu EDA, trước hết cần nắm được các bộ phận cấu thành và đường đi của sự kiện. Sơ đồ dưới đây mô tả cấu trúc tổng thể của EDA.

flowchart LR
  P1["Producer A<br/>(dịch vụ đơn hàng)"] -->|OrderCreated| CH["Kênh/broker sự kiện<br/>(Kafka·RabbitMQ)"]
  P2["Producer B<br/>(dịch vụ hội viên)"] -->|UserSignedUp| CH
  CH -->|đăng ký| C1["Consumer 1<br/>(xử lý thanh toán)"]
  CH -->|đăng ký| C2["Consumer 2<br/>(trừ tồn kho)"]
  CH -->|đăng ký| C3["Consumer 3<br/>(gửi thông báo)"]
  C1 -.->|PaymentCompleted| CH
  style CH fill:#e8f0fe,stroke:#2f6fed,stroke-width:2px

Bên sản xuất sự kiện (Producer) là chủ thể tạo ra sự kiện và phát hành nó tại thời điểm xảy ra thay đổi trạng thái. Nguyên tắc thiết kế quan trọng ở đây là sự kiện phải chứa "điều gì đã xảy ra (fact)" chứ không phải "hãy làm gì (command)". Chẳng hạn, phải phát hành "đơn hàng đã được tạo" chứ không phải "hãy thanh toán", như vậy bên sản xuất mới không can thiệp vào cách xử lý của bên tiêu thụ và liên kết được giữ lỏng. Bên sản xuất hoàn tất giao dịch của mình ngay khi phát hành sự kiện và không tham gia vào quá trình xử lý sau đó.

Kênh/broker sự kiện (Channel/Broker) là lối đi đồng thời là bộ đệm cho sự kiện. Tiêu biểu có Apache Kafka, RabbitMQ, AWS EventBridge, NATS. Broker là bộ phận cốt lõi tách rời (decoupling) vật lý bên sản xuất và bên tiêu thụ, cung cấp tính bền vững (durability): lưu giữ sự kiện ngay cả khi bên tiêu thụ tạm thời ngừng hoạt động và chuyển giao khi hoạt động trở lại. Đặc biệt, Kafka không xóa sự kiện mà lưu giữ dưới dạng log, cho phép cả những bên tiêu thụ tham gia muộn cũng có thể phát lại (replay) các sự kiện quá khứ từ đầu. Đặc tính này là nền tảng cho Event Sourcing sẽ được trình bày ở phần sau.

Bên tiêu thụ sự kiện (Consumer) đăng ký các sự kiện quan tâm và thực thi logic nghiệp vụ thực tế. Bên tiêu thụ có thể phát hành sự kiện mới như kết quả xử lý (PaymentCompleted trong hình trên), và chuỗi này hoàn thiện quy trình nghiệp vụ. Điều quan trọng nhất khi thiết kế bên tiêu thụ là tính lũy đẳng (idempotency). Để đề phòng sự cố mạng, broker thường đảm bảo chuyển giao ít nhất một lần (at-least-once), nghĩa là cùng một sự kiện có thể đến hai lần. Do đó bên tiêu thụ phải được thiết kế sao cho xử lý cùng một sự kiện nhiều lần vẫn cho kết quả như xử lý một lần (ví dụ: loại bỏ trùng lặp dựa trên ID sự kiện).

Bộ trung gian (Mediator) là thành phần đặc thù chỉ xuất hiện trong topology trung gian, chỉ huy tập trung thứ tự xử lý sự kiện qua nhiều bước và các nhánh điều kiện. Vai trò và phương án thay thế của nó sẽ được trình bày chi tiết ở mục tiếp theo.

3. Topology trung gian so với topology broker

Hai topology tiêu biểu của EDA phân nhánh ở câu hỏi "ai chịu trách nhiệm điều phối luồng nghiệp vụ phức tạp". Sơ đồ dưới đây đối chiếu cách mỗi topology xử lý cùng một nghiệp vụ 'xử lý đơn hàng'.

flowchart TB
  subgraph MED["Topology trung gian (Mediator) — Orchestration"]
    direction LR
    E1["Sự kiện đơn hàng"] --> M["Mediator<br/>(chỉ huy luồng)"]
    M -->|1| P["Thanh toán"]
    M -->|2| I["Tồn kho"]
    M -->|3| D["Giao hàng"]
    P -.kết quả.-> M
    I -.kết quả.-> M
  end
  subgraph BRK["Topology broker (Broker) — Choreography"]
    direction LR
    E2["Sự kiện đơn hàng"] --> B1["Thanh toán"] -->|đã thanh toán| B2["Tồn kho"] -->|đã trừ kho| B3["Giao hàng"]
  end
  style M fill:#e8f0fe,stroke:#2f6fed,stroke-width:2px

A. Topology trung gian — Điều phối tập trung (Orchestration)

Topology trung gian có một bộ trung gian (orchestrator) ở trung tâm kiểm soát toàn bộ luồng như một nhạc trưởng. Giống như nhạc trưởng dàn nhạc chỉ định thời điểm diễn tấu của từng nhạc cụ, bộ trung gian biết thứ tự và điều kiện "thanh toán trước, nếu thành công thì trừ tồn kho, sau đó bắt đầu giao hàng" và gọi lần lượt từng bộ xử lý. Ưu điểm lớn nhất của cách này là khả năng quan sát luồng. Vì toàn bộ kịch bản nghiệp vụ được biểu diễn tường minh tại một nơi là bộ trung gian, việc xác định và truy vết sự cố xảy ra ở bước nào trở nên dễ dàng.

Cách này đặc biệt phù hợp với các nghiệp vụ phức tạp đòi hỏi thứ tự nghiêm ngặt và rẽ nhánh điều kiện qua nhiều bước (ví dụ: thẩm định yêu cầu bồi thường bảo hiểm, quy trình phê duyệt khoản vay). Lý do là bộ trung gian có thể biểu diễn rõ ràng những nghiệp vụ mang tính máy trạng thái (state machine), trong đó hành động tiếp theo thay đổi tùy theo thành công hay thất bại của từng bước. Trong thực tế, các workflow engine như Conductor của Netflix, Cadence của Uber cùng hậu duệ là Temporal, và AWS Step Functions đảm nhận vai trò bộ trung gian này.

Tuy nhiên, topology trung gian cũng có cái giá phải trả. Thứ nhất, bộ trung gian có thể trở thành nút cổ chai và điểm lỗi duy nhất (SPOF). Vì mọi luồng đều đi qua bộ trung gian, hiệu năng của nó trở thành giới hạn trên của tổng thông lượng, và nếu bộ trung gian sập thì toàn bộ nghiệp vụ tương ứng dừng lại. Thứ hai, vì các bộ xử lý được điều phối gián tiếp thông qua bộ trung gian nên mức độ liên kết tương đối cao hơn topology broker. Để thêm một bước mới, thường phải sửa định nghĩa luồng của bộ trung gian.

B. Topology broker — Điều phối phân tán (Choreography)

Topology broker là phương thức phản ứng dây chuyền (chain reaction) không có bộ điều phối trung tâm: mỗi bộ xử lý khi nhận sự kiện sẽ làm việc của mình rồi phát hành kết quả dưới dạng sự kiện để kích hoạt bộ xử lý tiếp theo. Nó được ví như vũ đạo (choreography), trong đó các vũ công hoàn thành màn múa tập thể bằng cách phản ứng với động tác của nhau mà không có nhạc trưởng. Khi dịch vụ thanh toán phát hành "đã thanh toán", dịch vụ tồn kho nghe thấy, trừ kho rồi phát hành "đã trừ kho", và tiếp đó dịch vụ giao hàng phản ứng.

Ưu điểm của cách này là mức liên kết cực thấp và khả năng mở rộng vượt trội. Không có bộ điều phối trung tâm nên không có nút cổ chai, và mỗi dịch vụ có thể được triển khai và mở rộng hoàn toàn độc lập. Khi thêm một dịch vụ mới quan tâm đến sự kiện "đã thanh toán" (ví dụ: cộng điểm tích lũy), không cần đụng đến các dịch vụ hiện có. Vì vậy nó phù hợp với xử lý sự kiện khối lượng lớn, đơn giản và ưu tiên hàng đầu là khả năng mở rộng.

Ngược lại, điểm yếu lớn nhất là khó truy vết toàn bộ luồng. Logic nghiệp vụ nằm rải rác ở nhiều dịch vụ nên khó nắm bắt ngay "đơn hàng này hiện đã tiến tới đâu trong toàn bộ quy trình", và có nguy cơ xuất hiện phụ thuộc vòng (A→B→A) hoặc chuỗi phản ứng ngoài dự kiến. Vì thế trong topology broker, việc đảm bảo khả năng quan sát (observability) thông qua truy vết phân tán (distributed tracing) và ID tương quan (correlation ID) là bắt buộc.

C. So sánh hai topology

Tiêu chí Topology trung gian Topology broker
Cách điều phối Bộ trung gian trung tâm chỉ huy luồng (orchestration) Phản ứng dây chuyền không có điều phối trung tâm (choreography)
Mức liên kết Tương đối cao Rất thấp
Khả năng quan sát luồng Cao (tập trung tại một nơi) Thấp (phân tán ở nhiều dịch vụ)
Nghiệp vụ phù hợp Nghiệp vụ tuần tự, rẽ nhánh điều kiện phức tạp Xử lý sự kiện đơn giản, mở rộng cao
Điểm yếu chính Nút cổ chai, SPOF tại bộ trung gian Rủi ro khó truy vết luồng, phụ thuộc vòng
Công nghệ tiêu biểu Temporal, AWS Step Functions Pub/sub thuần dựa trên Kafka

Lý do căn bản tạo ra sự khác biệt giữa hai topology nằm ở "vị trí của logic nghiệp vụ". Topology trung gian gom logic luồng nghiệp vụ về trung tâm, còn topology broker phân tán nó vào từng dịch vụ. Do đó tiêu chí lựa chọn cũng rõ ràng — nếu luồng phức tạp và việc kiểm toán, truy vết là quan trọng thì chọn trung gian; nếu luồng đơn giản và khả năng mở rộng, tính độc lập là quan trọng thì chọn broker. Trong thực tế, thay vì chia nhị phân, người ta thường dùng cách kết hợp (hybrid): ở ranh giới domain lớn thì để lỏng bằng choreography, còn các giao dịch phức tạp bên trong thì điều phối bằng orchestration.

4. Tình huống thực tế và giao dịch phân tán — mẫu Saga

Bức tường đầu tiên gặp phải khi áp dụng EDA thực tế là giao dịch phân tán. Trong một DB duy nhất, có thể đảm bảo "tất cả thành công hoặc tất cả hủy bỏ" bằng giao dịch ACID, nhưng khi thanh toán, tồn kho, giao hàng nằm ở các dịch vụ và DB khác nhau thì không thể đảm bảo tính nguyên tử như vậy. Lúc này xuất hiện mẫu Saga (Saga pattern): nối chuỗi các giao dịch cục bộ trải trên nhiều dịch vụ bằng sự kiện, và nếu thất bại giữa chừng thì thực thi giao dịch bù (compensating transaction) để hoàn tác những công việc đã thành công trước đó. Ví dụ, nếu thất bại ở bước giao hàng, các sự kiện bù "khôi phục tồn kho", "hủy thanh toán" được phát hành theo thứ tự ngược. Saga chia thành Saga orchestration (bộ trung gian chỉ huy cả phần bù) và Saga choreography (mỗi dịch vụ tự phát hành sự kiện bù), gắn trực tiếp với việc lựa chọn hai topology.

Xem các tình huống công nghiệp cụ thể sẽ thấy rõ hiệu quả. Thứ nhất, Netflix có hàng nghìn microservice cộng tác thông qua sự kiện dựa trên Kafka, và dùng Conductor tự phát triển để điều phối workflow. Các dịch vụ phát video, gợi ý, tính phí được liên kết lỏng qua sự kiện, nên dù xử lý hàng tỷ sự kiện mỗi ngày, từng dịch vụ vẫn có thể được triển khai độc lập. Thứ hai, Uber ban đầu gặp vấn đề của cách choreography (khó truy vết luồng) và đã phát triển Cadence (nay là Temporal) để quản lý các workflow chạy dài như điều phối xe, tính cước theo cách trung gian. Thứ ba, các nền tảng thương mại điện tử áp dụng mẫu Saga cho xử lý đơn hàng, xây dựng bằng sự kiện luồng tự động hoàn trả tồn kho và gửi thông báo cho người dùng khi thanh toán thất bại. Các tình huống này minh chứng nguyên tắc lựa chọn "xử lý sự kiện đơn giản thì dùng broker, giao dịch phức tạp thì dùng trung gian".

5. Chuyên sâu — Event Sourcing, CQRS và xu hướng mới nhất

EDA tự nó là một kiến trúc hoàn chỉnh, nhưng cũng đang phát triển khi kết hợp với hai mẫu chuyên sâu. Thứ nhất, Event Sourcing là cách lưu trạng thái ứng dụng không phải dưới dạng giá trị hiện tại mà là "chuỗi tất cả các sự kiện đã xảy ra để dẫn đến trạng thái đó". Lấy tài khoản ngân hàng làm ví dụ, thay vì lưu số dư hiện tại 100.000 won, ta lưu chuỗi sự kiện "nạp 50.000, nạp 80.000, rút 30.000" và phát lại khi cần để tính số dư. Cách này cung cấp khả năng vết kiểm toán (audit trail) hoàn hảo và khôi phục về thời điểm quá khứ (time travel), nhưng phải trả giá bằng gánh nặng tính lại trạng thái mỗi lần và khó khăn khi thay đổi lược đồ sự kiện (schema evolution).

Thứ hai, CQRS (Command Query Responsibility Segregation) là mẫu tách mô hình lệnh (Command) thay đổi dữ liệu khỏi mô hình truy vấn (Query) đọc dữ liệu. Khi kết hợp với EDA và Event Sourcing, việc ghi được xử lý bằng sự kiện, còn việc đọc do một mô hình chỉ-đọc riêng (read model) được tạo ra bằng cách tiêu thụ sự kiện đảm nhận. Nhờ đó có thể tối ưu hóa và mở rộng đọc và ghi độc lập, nhưng giữa mô hình ghi và mô hình đọc sẽ phát sinh độ trễ thời gian gọi là nhất quán cuối cùng (eventual consistency). Điều này có nghĩa là dữ liệu người dùng vừa ghi có thể chỉ được phản ánh trong truy vấn sau vài mili giây đến vài giây, và cần thiết kế xử lý vấn đề này ở cấp độ UX.

Về xu hướng mới nhất, nổi bật là sự chuẩn hóa của các nền tảng streaming sự kiện. Apache Kafka đã trở thành xương sống sự kiện chuẩn trên thực tế, và trên cloud, định tuyến sự kiện serverless (AWS EventBridge, Google Eventarc) đang lan rộng. Ngoài ra, để đảm bảo khả năng tương tác của định dạng sự kiện, đặc tả CloudEvents của CNCF đã ra đời, thể hiện nỗ lực chuẩn hóa siêu dữ liệu sự kiện không phụ thuộc nhà cung cấp. Ở góc độ dữ liệu, EDA cũng đang mở rộng điểm giao với khái niệm Data Mesh, trong đó mỗi dịch vụ tự phát hành và sở hữu dữ liệu thuộc domain của mình dưới dạng sự kiện. Những xu hướng này cho thấy EDA đang vượt ra ngoài một phương thức giao tiếp đơn thuần để trở thành trục tái cấu trúc toàn bộ kiến trúc dữ liệu.

6. Những điểm cần cân nhắc và hàm ý

EDA mạnh mẽ nhưng không phải thuốc chữa bách bệnh, và khi áp dụng cần đánh giá tổng hợp các điểm sau dưới góc nhìn của Kỹ sư chuyên nghiệp (Professional Engineer).

  1. Việc chọn topology do độ phức tạp nghiệp vụ và yêu cầu kiểm toán quyết định. Nếu cần điều phối nhiều bước theo thứ tự và điều kiện nghiêm ngặt, hoặc quy định bắt buộc phải truy vết luồng, hãy chọn topology trung gian; nếu đơn giản và ưu tiên hàng đầu là khả năng mở rộng, tính độc lập của dịch vụ, hãy chọn topology broker. Trong thực tế, chiến lược kết hợp — ranh giới domain dùng choreography, giao dịch phức tạp bên trong dùng orchestration — là hiện thực nhất.

  2. Thiết kế nhất quán cuối cùng và xử lý lỗi quyết định thành bại. Xử lý bất đồng bộ đổi tính nhất quán tức thời lấy khả năng mở rộng. Vì vậy, lấy nhất quán cuối cùng làm tiền đề, nhất thiết phải thiết kế đồng bộ Saga và giao dịch bù, cơ chế thử lại (retry) và lùi thời gian (backoff), hàng đợi thư chết (Dead Letter Queue), cùng tính lũy đẳng của bên tiêu thụ. Bỏ sót những yếu tố này, tính toàn vẹn dữ liệu sẽ sụp đổ do mất hoặc xử lý trùng sự kiện.

  3. Cần đầu tư chủ động vào khả năng quan sát (observability). Luồng càng phân tán thì càng khó truy vết "điều gì đã xảy ra và đến đâu". Phải lan truyền ID tương quan theo từng sự kiện, và xây dựng từ đầu truy vết phân tán (OpenTelemetry), ghi log tập trung, giám sát luồng sự kiện để giảm chi phí gỡ lỗi ở giai đoạn vận hành.

  4. Cần đánh giá tỉnh táo mức độ trưởng thành của tổ chức và các đánh đổi. EDA chắc chắn làm tăng độ phức tạp phát triển và vận hành. Ở giai đoạn đầu chỉ có vài dịch vụ và lưu lượng không lớn, lời gọi đồng bộ có thể đơn giản và hiệu quả hơn. Lợi ích của EDA chỉ vượt chi phí khi tổ chức có năng lực vận hành độc lập nhiều dịch vụ (DevOps, giám sát, cơ chế trực on-call). Chiến lược an toàn là áp dụng từ domain cốt lõi rồi mở rộng dần.

  5. Cần có tầm nhìn về hướng tiến hóa cùng các công nghệ liên quan. EDA đang phát triển nhờ kết hợp với MSA, Event Sourcing, CQRS, Data Mesh, và các tiêu chuẩn như CloudEvents cùng định tuyến sự kiện serverless đang hạ thấp rào cản áp dụng. Về lâu dài, tầm quan trọng chiến lược của EDA như một xương sống streaming kết nối dữ liệu thời gian thực với pipeline suy luận AI được dự báo sẽ còn tăng lên.

Tài liệu tham khảo


Tóm tắt một câu: EDA là kiến trúc liên kết lỏng các thành phần thông qua phát hành và đăng ký sự kiện, được hiện thực bằng topology trung gian (bộ điều phối trung tâm chỉ huy luồng) và topology broker (phản ứng dây chuyền không có bộ điều phối), trong đó thiết kế Saga, nhất quán cuối cùng, tính lũy đẳng và khả năng quan sát quyết định thành bại.