ADR-0001. EventBus nội bộ tiến trình + BullMQ cho luồng sự kiện (không Kafka)
| Trường | Giá trị |
|---|---|
| Status | Accepted |
| Ngày | 2026-04-01 |
| Người quyết định | Phat Nguyen |
| Thay thế | - |
Bối cảnh
- Helpdesk cần phản ứng với các sự kiện nghiệp vụ (tạo ticket, đổi trạng thái, phân công, thêm tin nhắn) và chạy các tác vụ nặng theo cơ chế bất đồng bộ (phân công, giám sát SLA, escalation, gửi thông báo, làm giàu ngữ cảnh, khảo sát).
- Chuẩn của nền tảng cho luồng sự kiện giữa các service là Kafka.
@platformatic/kafkathậm chí còn được khai báo trongpackage.json. - Tuy nhiên, mọi luồng sự kiện của helpdesk đều nằm trong một service: một sự kiện do use-case phát ra được một listener trong chính service đó tiếp nhận rồi phân phối ra các job chạy nền. Không service nào khác lắng nghe sự kiện của helpdesk, và helpdesk cũng không lắng nghe topic bên ngoài nào.
Quyết định
Dùng cơ chế hai tầng nội bộ service và không dùng Kafka:
EventBusnội bộ tiến trình (eventemitter3,EventBusComponent) - use-case phát sự kiệnTicketEventTypesquaTicketEmitter; các listener trongsrc/application/events/listeners/xử lý đồng bộ ngay trong tiến trình API. Lỗi của handler được bắt và ghi log, không bao giờ làm sập emitter.- Các queue BullMQ (
QueueComponent,WorkerComponent) - listener phân phối ra các queue bền vững lưu trên Redis; một worker process riêng (RUN_MODE=worker) tiêu thụ chúng với cơ chế retry/backoff theo từng queue.
@platformatic/kafka vẫn được khai báo nhưng không dùng (dependency thừa).
Hệ quả
| Ưu | Nhược |
|---|---|
| Không phụ thuộc cụm Kafka cho một service khép kín | Sự kiện không quan sát được từ bên ngoài - service khác không thể lắng nghe |
| Phát sự kiện đồng bộ giúp response HTTP nhanh (tác vụ được hoãn cho BullMQ) | EventBus chạy theo cơ chế at-most-once; nếu sập giữa lúc phát và lúc đưa vào queue thì mất phần phân phối |
| BullMQ cho retry bền vững + DLQ mà không cần broker | Phải nắm hai mô hình phân phối (nội bộ tiến trình + queue) |
| Phát triển cục bộ đơn giản hơn (chỉ cần Redis) | Dependency @platformatic/kafka thừa gây hiểu lầm cho người đọc và làm phình quá trình cài đặt |
Phương án đã cân nhắc
| Tùy chọn | Vì sao bị từ chối |
|---|---|
| Kafka cho mọi luồng sự kiện | Quá cồng kềnh cho luồng nội bộ service; thêm phụ thuộc broker mà không có ai lắng nghe từ bên ngoài |
| Chỉ dùng BullMQ (không có bus nội bộ tiến trình) | Ép mọi phản ứng nghiệp vụ phải đi qua Redis ngay cả khi xử lý đồng bộ nội bộ tiến trình là đủ |
| Outbox giao dịch + CDC | Quá nặng cho một service không có ai tiêu thụ sự kiện từ bên ngoài |
Tham khảo
src/components/event-bus/event-bus.ts(eventemitter3)src/components/event-bus/event-registry.tssrc/application/events/emitters/ticket.emitter.tssrc/components/queue.component.tspackage.json(@platformatic/kafkađược khai báo, không dùng)