Skip to content

ADR-0001. EventBus in-process + BullMQ cho eventing (không Kafka)

TrườngGiá trị
StatusAccepted
Ngày2026-04-01
Người quyết địnhsupport-team
Thay thế

Bối cảnh

  • Helpdesk cần phản ứng với sự kiện domain (ticket created, status changed, assigned, message added) và chạy công việc nặng bất đồng bộ (assignment, giám sát SLA, escalation, thông báo, enrichment context, surveys).
  • Chuẩn nền tảng cho eventing cross-service là Kafka. @platformatic/kafka thậm chí được khai báo trong package.json.
  • Tuy nhiên, tất cả luồng event của helpdesk là trong-dịch-vụ: một event phát bởi một use-case được tiêu thụ bởi một listener trong cùng dịch vụ fan out tới job nền. Không dịch vụ nào khác đăng ký event helpdesk, và helpdesk không đăng ký topic bên ngoài nào.

Quyết định

Dùng một cơ chế trong-dịch-vụ hai tầng và không Kafka:

  1. EventBus in-process (eventemitter3, EventBusComponent) — use-case phát event TicketEventTypes qua TicketEmitter; listener trong src/application/events/listeners/ xử lý chúng đồng bộ trong API process. Lỗi handler được bắt và log, không bao giờ crash emitter.
  2. Hàng đợi BullMQ (QueueComponent, WorkerComponent) — listener fan out tới hàng đợi nền Redis bền vững; một worker process riêng (RUN_MODE=worker) tiêu thụ chúng với retry/backoff theo từng hàng đợi.

@platformatic/kafka vẫn được khai báo nhưng không dùng (dependency chết).

Hệ quả

ƯuNhược
Không phụ thuộc cụm Kafka cho một dịch vụ độc lậpEvent không quan sát được từ bên ngoài — dịch vụ khác không thể đăng ký
Emit đồng bộ giữ response HTTP nhanh (công việc hoãn cho BullMQ)EventBus là at-most-once; crash giữa emit và enqueue làm mất fan-out
BullMQ cho retry bền vững + DLQ mà không cần brokerHai mô hình phân phối (in-process + queue) phải suy luận
Dev cục bộ đơn giản hơn (chỉ cần Redis)Dep @platformatic/kafka chết gây hiểu lầm cho người đọc và phình install

Phương án đã cân nhắc

Tùy chọnVì sao bị từ chối
Kafka cho mọi eventingOver-engineer cho luồng trong-dịch-vụ; thêm phụ thuộc broker không có subscriber bên ngoài
Chỉ BullMQ (không bus in-process)Ép mọi phản ứng domain qua Redis ngay cả khi xử lý in-process đồng bộ là đủ
Outbox transactional + CDCNặng cho một dịch vụ không có consumer event bên ngoài

Tham khảo

  • src/components/event-bus/event-bus.ts (eventemitter3)
  • src/components/event-bus/event-registry.ts
  • src/application/events/emitters/ticket.emitter.ts
  • src/components/queue.component.ts
  • package.json (@platformatic/kafka được khai báo, không dùng)

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.