Ý chính: Kiến trúc hướng sự kiện chỉ đáng tin khi dữ liệu đã xác nhận không thể âm thầm mất sự kiện đi kèm.
Thuật ngữ trong bài: Outbox: bảng lưu sự kiện cùng giao dịch nghiệp vụ; relay: tiến trình chuyển sự kiện lên broker; idempotent: nhận lặp sự kiện nhưng chỉ tạo một kết quả.
Bài toán thực tế
Ghi cơ sở dữ liệu và gửi sự kiện là hai thao tác riêng. Nếu tiến trình dừng ở giữa, hệ thống có thể lưu dữ liệu nhưng mất sự kiện, hoặc gửi sự kiện cho dữ liệu chưa được xác nhận. Việc thử lại còn có thể tạo sự kiện trùng.
Broker giúp tách các dịch vụ theo thời gian, nhưng không tạo ra một giao dịch nguyên tử với cơ sở dữ liệu ứng dụng. Nếu ghi dữ liệu và phát sự kiện ở hai bước riêng, một lần dừng tiến trình đúng thời điểm có thể làm mất sự kiện hoặc tạo sự kiện cho dữ liệu chưa được ghi nhận.
Transactional Outbox giải quyết ranh giới ghi; consumer vẫn phải chịu được sự kiện trùng, đến muộn và được phát lại.
Thiết kế và triển khai
- Đặt tên sự kiện ở thì quá khứ để mô tả một sự thật đã xảy ra, thay vì dùng sự kiện như lời gọi hàm từ xa.
- Ghi thay đổi nghiệp vụ và bản ghi Outbox trong cùng một giao dịch cơ sở dữ liệu.
- Phát sự kiện bất đồng bộ; mỗi consumer lưu mã sự kiện đã xử lý để nhận trùng vẫn chỉ tạo một kết quả.
Mã minh họa: Ghi đơn hàng và Outbox trong cùng giao dịch
BEGIN
INSERT INTO orders (...) VALUES (...)
INSERT INTO outbox(id, aggregate_id, type, payload)
VALUES (:eventId, :orderId, 'OrderCreated.v1', :payload)
COMMIT
relay.publish_unpublished(limit = 500)Chỉ đánh dấu sự kiện đã phát sau khi broker xác nhận. Lease cho phép relay khác tiếp quản một lô bị bỏ dở.
Rủi ro cần tính trước
- Relay đã phát sự kiện nhưng dừng trước khi đánh dấu hoàn tất, khiến broker giao lại cùng sự kiện.
- Một sự kiện lỗi liên tục chặn cả partition nếu không có nơi cách ly và quy trình phát lại có kiểm soát.
- Consumer mới không tương thích với lược đồ của các sự kiện cũ vẫn còn được lưu giữ.
Nên theo dõi gì?
| Tín hiệu | Điều tín hiệu cho biết |
|---|---|
| Tuổi của bản ghi Outbox chưa được phát lâu nhất | Cho biết thay đổi đã ghi nhận bị chậm tới hệ thống phía sau bao lâu. |
| Độ trễ consumer theo loại sự kiện | Giúp tách một luồng nghiệp vụ chậm khỏi sự cố chung của broker. |
| Tỷ lệ sự kiện trùng và phát lại | Làm lộ relay thiếu ổn định hoặc consumer chưa thật sự an toàn khi nhận trùng. |
Đưa vào production từng bước
Chọn một tác động phụ ít rủi ro và chạy luồng sự kiện song song với luồng đồng bộ để đối chiếu. Hoàn thiện công cụ phát lại, bảng theo dõi sự kiện tồn đọng và người chịu trách nhiệm trước khi chuyển thêm consumer.
Điều cần nhớ
Kiến trúc hướng sự kiện đáng tin khi ranh giới giao dịch, chủ sở hữu sự kiện và cách thử lại đều được thể hiện rõ trong thiết kế.
