一、为什么要用"域"来设计
很多人做防伪溯源系统,第一反应是"建几张表、写几个接口"。结果做着做着,赋码、验真、追溯、营销全搅在一起,一个需求改动要改 10 个地方。这就是典型的"大泥球架构"。
我们的解法是领域驱动设计(DDD),把系统按业务域拆成 6 个独立模块。每个域有自己的数据库、自己的服务、自己的团队,通过事件总线解耦。
二、6 大域定义与职责
1. 赋码域(Code Domain)
- 职责:码生成、码池管理、产线赋码客户端。
- 核心实体:CodeBatch(码段)、Code(单码)、CodePool(码池)。
- 特点:写多、对一致性要求极高(不能重复)。
2. 验真域(Verify Domain)
- 职责:扫码验真、状态查询、异常封禁。
- 核心实体:VerifyResult、VerifyLog。
- 特点:读多、峰值极高(大促)、对延迟敏感。
3. 追溯域(Trace Domain)
- 职责:履历构建、链路查询、批次检索。
- 核心实体:TraceEvent(追溯事件)、TraceChain(链)。
- 特点:检索多、数据量大、读多写多。
4. 风控域(Risk Domain)
- 职责:批量伪造识别、地理围栏、窜货评分。
- 核心实体:RiskRule、RiskScore、Blacklist。
- 特点:计算密集、实时性要求高。
5. 分析域(Analytics Domain)
- 职责:扫码行为画像、复购预测、BI 看板。
- 核心实体:UserPortrait、Metric、Dashboard。
- 特点:离线批处理为主、容忍延迟。
6. 会员域(Member Domain)
- 职责:留资、积分、企微 SCRM、券营销。
- 核心实体:Member、Point、Coupon。
- 特点:和营销强绑定、写多。
三、域间关系:事件总线解耦
关键设计:所有跨域数据流通过 Kafka 事件总线传递,不互相直接 RPC 调用。
赋码域 ──CodeAssigned──▶ [Kafka] ──▶ 追溯域 / 验真域 / 分析域 验真域 ──CodeVerified──▶ [Kafka] ──▶ 风控域 / 分析域 / 会员域 风控域 ──RiskAlert────▶ [Kafka] ──▶ 会员域 / 告警好处:
- 赋码产生事件,验真/追溯/分析各自消费,互不影响;
- 新增一个"营销域",只需订阅现有事件,不改任何老代码;
- 某个域宕机,其他域照常运行(最终一致)。
四、统一商品 ID 设计
所有域打通的命脉,是统一商品 ID 体系。我们设计了 4 级:
| 层级 | 含义 | 粒度 | 谁用 |
|---|---|---|---|
| SPU | 产品级 | 如"茅台 53°500ml" | 品牌/BI |
| SKU | 规格级 | 同款不同年份 | 电商/库存 |
| BATCH | 批次级 | 同原料同产线 | 质检/召回 |
| CODE | 单件码 | 每瓶唯一 | 赋码/验真/追溯 |
所有域的数据库都以 CODE 为最细粒度主键,向上聚合到 SPU 查询。这样消费者扫一瓶码,能追溯到它属于哪个 SPU、哪一批;仓储扫一箱码,能拆出 N 个瓶码;产线赋一个码,自动归属到批次和 SKU。
五、部署与扩容策略
每个域独立部署、独立扩容:
- 验真域:大促前独立加节点 + Redis 副本(读多);
- 赋码域:按产线水平扩展(写多);
- 追溯域:只读副本分流查询;
- 分析域:弹性/定时跑批,大促时可临时缩容。
六、MVP 建议与避坑
别一上来就搞 6 个域。我们的节奏:
- MVP(第 1 月):赋码 + 验真 + 追溯 3 域跑通闭环;
- 第 2 月:加风控域(防窜货);
- 第 3 月:加分析域(BI);
- 第 4 月:加会员域(私域)。
避坑:域间不要共享数据库!共享数据库 = 伪微服务,最终还是会耦合。数据通过事件传递,接受"最终一致"。