Tóm tắt: Broker chỉ giữ thứ tự trong một phạm vi nhất định. Nghiệp vụ phải xác định những sự kiện nào thật sự cần đi cùng thứ tự.
Thuật ngữ chính: Ordering: thứ tự sự kiện; deduplication: loại sự kiện trùng; replay: phát lại sự kiện cũ để dựng lại dữ liệu.
Bài toán
Giữ thứ tự toàn hệ thống làm giảm khả năng xử lý song song. Thử lại tạo sự kiện trùng, còn sự kiện đến muộn có thể ghi đè dữ liệu mới. Phát lại lịch sử cũng có thể gửi lại email hoặc thanh toán nếu không tách tác động bên ngoài.
Vì sao cách làm đơn giản chưa đủ
OrderCreated và OrderCancelled cần thứ tự trong một order, không phải toàn bộ khách hàng. Partition theo order ID giữ đúng guarantee hữu ích và vẫn scale.
sự kiện time, ingestion time và processing time khác nhau. Business rule phải nói rõ thời gian nào điều khiển window và conflict resolution.
Luồng xử lý
aggregate phiên bản→Partition
local order theo key→bộ phận nhận sự kiện
inbox và phiên bản check→Replay
cô lập tác động phụ
Quyết định kiến trúc
phiên bản aggregate
Aggregate phiên bản tăng dần giúp bộ phận nhận sự kiện phát hiện duplicate, gap và stale sự kiện.
Park gap mà không chặn mọi thứ
thử lại hoặc quarantine một aggregate trong khi key khác tiếp tục nếu broker cho phép.
bộ phận nhận sự kiện phải replay-safe
Tách trạng thái projection thuần khỏi email, payment, webhook và chặn tác động phụ khi replay.
Phân tích chuyên sâu
Exactly once là kết quả
Broker transaction có thể giảm duplicate. Tuy nhiên, cơ sở dữ liệu và API ngoài vẫn cần idempotent business key.
Schema và ý nghĩa cùng thay đổi
sự kiện đúng cú pháp vẫn có thể đổi nghĩa. Lưu semantic phiên bản note và test fixture cũ với bộ phận nhận sự kiện mới.
Các bước triển khai
- Chọn partition key trùng với business ordering ranh giới.
- Mang mã sự kiện, aggregate ID, aggregate phiên bản và occurred time.
- Tách rebuild trạng thái khỏi external tác động phụ khi replay.
Ví dụ kỹ thuật: bộ phận nhận sự kiện hiểu phiên bản
if inbox.contains(event.id): ACK
current = projection.version(event.aggregateId)
if event.version <= current: ACK
if event.version > current + 1: park(event)
transaction(apply(event), inbox.add(event.id))
ACKGap bị park cần alert và recovery chính sách. Chờ vô hạn chính là silent data loss.
Các tình huống lỗi cần tính trước
- bộ phận phát sự kiện reset aggregate phiên bản sau data migration.
- Replay gửi lại notification cho khách hàng.
- Một hot aggregate làm bão hòa partition.
Tín hiệu cần giám sát
| Tín hiệu | Ý nghĩa |
|---|---|
| Tỷ lệ gap và stale sự kiện | Lộ lỗi ordering và bộ phận phát sự kiện phiên bản. |
| Deduplication hit rate | Cho thấy thử lại và delivery bất ổn. |
| Replay thông lượng và tác động phụ bị chặn | Làm rõ tiến độ cùng độ an toàn recovery. |
Cách kiểm chứng thiết kế
- Xáo trộn, nhân đôi và trì hoãn chuỗi sự kiện đại diện.
- Replay lịch sử gần môi trường thật vào projection cô lập.
- Tạo hot partition và kiểm tra key khác vẫn đạt mục tiêu.
Kế hoạch triển khai an toàn
Thêm metadata và quan sát trước khi enforcement phiên bản. Đưa inbox deduplication vào một bộ phận nhận sự kiện rồi tạo replay-only môi trường. Diễn tập toàn bộ lịch sử trước khi dùng replay trong incident recovery.
Checklist trước khi đưa vào vận hành
- Ordering requirement được ghi theo từng sự kiện stream.
- bộ phận nhận sự kiện chịu được duplicate và delayed delivery.
- Replay có destination, rate limit và side-effect chính sách.
Kết luận
Tính đúng của message đến từ business order rõ ràng và bộ phận nhận sự kiện xác định, không chỉ từ lời hứa của broker.
