Skip to content

ADR-0002. CDC (Debezium) làm seam tích hợp — Kafka chỉ producer

TrườngGiá trị
StatusAccepted
Ngày2026-03-15
Người quyết địnhcommerce-team, platform-team
Thay thế

Bối cảnh

  • Commerce là nguồn sự thật catalog/tenant. Nhiều dịch vụ cần dữ liệu của nó: search (index products/merchants/categories), inventory (seed locations + items), pricing (init fares), taxation (cấp phát nhóm thuế), invoice (suy ra TaxInfo).
  • Produce Kafka cấp ứng dụng sẽ buộc commerce phải biết mọi hợp đồng downstream, phát một topic cho mỗi hình dạng thay đổi, và giữ code emit đồng bộ với mọi mutation catalog qua nhiều dịch vụ — gắn kết cao và dễ bỏ sót một đường ghi.
  • Postgres đã ghi mọi thay đổi trong WAL. Debezium có thể capture nó một cách tổng quát.

Quyết định

Dùng CDC (Debezium) làm seam tích hợp chính. Nghĩa vụ duy nhất của commerce là ghi đúng vào Postgres; Debezium đọc WAL và publish một topic cho mỗi bảng (CDCKafkaTopics / CdcTables trong @nx/core, ví dụ public.Merchant, public.ProductVariant).

  • Các consumer downstream (search/inventory/pricing/taxation/invoice) sở hữu đấu nối CDC consumer của riêng họ.
  • ApplicationKafkaComponent của commerce bind một producer thuần — và thực tế không gọi .send() ở bất cứ đâu trong src/. Một khóa binding APPLICATION_KAFKA_CONSUMER được khai báo nhưng không có consumer nào được đấu nối.
  • CDC consumer duy nhất mà chính commerce chạy là ApplicationCdcComponent (từ @nx/search, vai trò WORKER) để đồng bộ DB của chính nó vào Typesense.
  • Thông tin thuế merchant minh họa mẫu hình này: ghi vào Merchant.metadata.tax, được capture bởi CDC, và được upsert vào TaxInfo bởi @nx/invoice (nguồn đọc downstream có thẩm quyền).

Hệ quả

ƯuNhược
Không code emit theo từng consumer trong commerce; consumer mới gắn vào mà không cần đổi commerceConsumer gắn với schema bảng — đổi tên cột là phá vỡ
Không có rủi ro "quên emit trên đường ghi này"CDC thêm Debezium/Kafka Connect làm phụ thuộc vận hành
Thứ tự WAL + replay offset cho phân phối bền, có thể replayNhất quán cuối cùng; consumer phải idempotent theo PK
Producer giữ lại cho dùng tương lai mà không ép buộc ngayMột producer được bind-nhưng-nhàn-rỗi có thể gây nhầm lẫn cho người mới (tài liệu hóa ở đây)

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

Tùy chọnƯuNhượcVì sao bị từ chối
Produce Kafka cấp ứng dụng theo từng thay đổiPayload tường minh, được tuyển chọnGắn kết cao; phải instrument mọi đường ghi trong mọi dịch vụDễ vỡ; phá vỡ tính đơn giản của nguồn sự thật
Fan-out HTTP đồng bộ trên mỗi mutationTức thìGắn kết runtime chặt; lỗi lan tỏa; ghi chậmBán kính tác động không chấp nhận được
Bảng outbox + relayĐảm bảo transactionalTái phát minh thứ Debezium cho miễn phí trên WALDebezium đã bao quát

Tham khảo

  • packages/core/src/common/cdc/tables.ts (CdcTables)
  • packages/core/src/common/kafka/topics.ts (CDCKafkaTopics)
  • src/components/kafka/component.ts (producer được bind, không .send())
  • src/common/keys.ts (APPLICATION_KAFKA_CONSUMER được khai báo, không dùng)
  • src/services/merchant.service.ts (tax → metadata.tax → CDC → TaxInfo)

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