1. 立项背景与目标
业务同时经营自营商城、亚马逊、TikTok Shop 三个渠道,各渠道订单格式、状态语义、退款规则完全不同。早期靠运营每天手工导单、Excel 对库存,月均出现 30 单以上超卖,重复发货每月 5–8 单,财务对账需要 2 人天且经常对不平。立项目标是把订单、库存、履约、售后收敛成一套统一模型:支撑日均 80 万单、大促峰值 3000 TPS,超卖归零,对账差异可自动定位。
2. 软件功能与核心模块
渠道适配层:以 SPI 插件方式接入各平台,负责签名验签、拉单/推单、字段归一化,新增一个渠道只需实现一套接口,不改核心代码。
订单中心:统一订单模型 + 状态机 + 订单快照,承载订单创建、拆合单、审核、取消、状态流转与全链路轨迹。
库存中心:多渠道共享库存池,提供预占、释放、回补、安全库存与超卖保护。
履约中心:拣货波次、面单获取、发货回传、物流轨迹订阅、异常件工单。
售后中心:仅退款、退货退款、换货、部分退款,按渠道规则差异化编排。
对账中心:T+1 拉取渠道账单与本地资金流水做多维度比对,输出差异明细与自动补偿建议。
开放平台:为商家 ERP 提供订单、库存、发货的 OpenAPI 与消息推送。
3. 业务流程与功能路径
渠道下单 → 适配层归一化并写入渠道原始报文 → 订单中心幂等落单(业务唯一键:渠道 + 渠道单号)→ 库存预占 → 支付回调驱动状态机流转 → 风控/人工审核 → 拆单推送 WMS → 发货回传 → 物流签收 → T+1 对账 → 差异进入异常工单池。
功能路径示例:商家后台 → 订单列表(多条件检索)→ 订单详情(含快照、轨迹、资金)→ 操作(改地址/取消/补发)→ 操作日志留痕。
1. 整体架构与设计思路
按 DDD 划分限界上下文,订单、库存、履约、售后各自独立服务,服务内分层为 interfaces / application / domain / infrastructure。核心链路采用「同步落单 + 异步驱动」:下单只做幂等、校验、预占三件事并快速返回,后续履约、通知、对账全部走 RocketMQ 事件。跨服务一致性放弃强事务,统一用「本地消息表 + RocketMQ 事务消息 + 消费端幂等」实现最终一致。订单库按 buyer_id 哈希分 16 库 64 表,历史订单按年归档到冷库;商家/时间/状态等非分片维度查询走 Elasticsearch 二级索引,DB 只承接点查与写入。
2. 我负责的模块与结果
负责订单中心、库存中心与对账中心的设计与实现,主导分库分表方案落地与三次大促压测。
订单创建接口 P99 由 480ms 降至 95ms,大促峰值 3200 TPS 稳定运行,错误率 0.02%。
超卖由月均 30+ 单降至 0;重复发货由每月 5–8 单降至 0。
对账差异定位由 2 人天缩短至 15 分钟(差异自动归类 + 定位到具体订单与流水)。
订单查询切 ES 后,MySQL 读压力下降约 70%,列表页 P99 从 1.6s 降到 220ms。
3. 难点、坑与解决方案
渠道重复推送 + 事件乱序:同一订单可能收到「已取消」再收到「已支付」。做法是给每个渠道事件打上渠道版本号与事件时间,落库前用状态机做非法迁移拦截(非法迁移不报错、进异常池),异常池按订单聚合后自动重放,重放仍失败的转人工。上线后订单状态错乱工单归零。
热点 SKU 库存行锁竞争:秒杀时单行 UPDATE 直接把连接池打满。改为 Redis 分段库存:一个 SKU 拆 10 个桶,按请求哈希取模做 Lua 原子预占,DB 只做异步最终扣减与对账校准,桶余量不足时降级为单桶串行。
分库分表后的多维查询:分片键是 buyer_id,但运营要按商家 + 时间查。用基因法把商家 ID 的低位基因写入分片键,同时把列表查询整体迁到 ES,双写用 binlog 订阅保证最终一致。
大促前压测发现 MQ 堆积:消费端改成批量拉取(500 条/批)+ 业务线程池按渠道隔离,慢渠道不拖累快渠道,并加了堆积告警与自动扩容策略。