在电商业务中,核心交易链路(Trading Flow)是整个系统的骨干。它涵盖了用户从产生购买意向到最终完成交易、完成售后循环的端到端全生命周期。主干流程通常可以划分为:导购、商品详情页(PDP)、购物车、结算确认(Checkout)、支付、履约、逆向(售后)以及客服闭环。

全链路总览

flowchart TB subgraph 前台导购域 ["前台导购域"] A[搜索/推荐/会场] --> B[PDP 商品详情] end subgraph 核心交易域 ["核心交易与结算域"] B --> C[加购/购物车] C --> D[Checkout 结算中心] subgraph Checkout 内部逻辑 ["Checkout 提单校验与生成"] D --> D1[风控合规校验] D --> D2[复杂优惠计算] D --> D3[库存预占/扣减] D --> D4[订单生成/快照固化] end D4 --> E[收银台与支付] end subgraph 履约与售后域 ["履约与逆向履约域"] E --> F{支付结果判断} F -->|成功| G[履约路由与WMS下发] G --> H[仓配/发货/签收] F -->|失败或超时| I[关单/释放资源] H --> J[售后逆向流程] J --> K[退款/退货/换货] H --> L[客服与工单触点] J --> L end L -.->|数据回流与策略反哺| A

各环节目标和关键动作

导购

目标:让用户高效找到想买的商品并产生点击。 关键动作:

PDP(商品详情页)

目标:完成“种草 + 信任建立 + 购买决策”。 关键动作:

购物车

目标:沉淀购买意向,并作为结算前的统一收敛层。 关键动作:

Checkout(结算确认)

目标:在“正确、安全、可审计”的前提下生成可支付订单。

风控合规

优惠计算

库存预占与扣减

订单生成与持久化

支付

目标:安全完成资金流转,并与订单状态可靠对账。 关键动作:

履约单生成

目标:把订单转化为可执行的供应链动作。 关键动作:

逆向售后

目标:在可控成本下解决用户纠纷与退款诉求,保障用户复购率。 关键动作:

客服闭环

目标:兜底全链路异常,沉淀体验缺陷并反哺系统策略。 关键动作:


导购域核心:高并发搜推广(Search-Recommend-Promote)架构

导购域是电商交易的流量入口与成交决策起点。现代电商的搜索、推荐与广告(搜推广)系统,通过千人千面的个性化算法,在极低延迟(通常要求全链路响应时间 RT < 50ms)下,从数千万甚至亿级商品库中实时匹配出最符合当前用户意图与状态的商品。

搜推广全链路架构

搜推广系统的核心工作流程是一个典型的“漏斗模型”,主要划分为:大/小召回(Retrieval) -> 多路归并 -> 粗排(Pre-ranking) -> 精排(Fine Ranking) -> 重排(Re-ranking) 等阶段。

flowchart TD A[海量商品库 Millions of SKUs] --> B(大召回 Broad Recall) A --> C(小召回 Real-time/Targeted Recall) subgraph 大召回渠道 ["大召回 (Broad Recall) - 求广与快 (~5000 候选)"] B1[ES 倒排索引检索 BM25] B2[协同过滤 ItemCF/UserCF] B3[热门/运营规则/分类检索] end B --> B1 & B2 & B3 subgraph 小召回渠道 ["小召回 (Targeted Recall) - 求精与准 (~200 候选)"] C1[向量检索 DSSM/MIND 双塔] C2[Flink 实时行为序列触发] C3[地理位置/实时库存过滤] end C --> C1 & C2 & C3 B1 & B2 & B3 & C1 & C2 & C3 --> D[多路归并与去重 Merge & Deduplicate] D --> E[粗排 Pre-ranking: 逻辑回归/轻量级 DNN] E --> F[精排 Fine Ranking: 深度学习模型 DIN/DIEN] F --> G[重排 Re-ranking: 多样性/打散/商业化规则] G --> H[最终展示给用户 Top-K 展示]

千人千面与多维画像

个性化推荐的基石是用户画像与商品画像的精准匹配:

检索基石:Elasticsearch 引擎

在搜索和特定召回路径中,Elasticsearch(ES)承担着轻量级检索与硬性条件过滤的重任:

大召回(Broad Recall)

小召回(Targeted/Real-Time Recall)

召回协同与精细排序

大召回和小召回的候选集在多路归并模块中进行合并,并去除重复商品。合并后的候选集会依次经历:

营销会场搭建与动态渲染流程

营销会场(如大促主会场、品类分会场)是电商大促期间的流量聚集地。高效的会场搭建与渲染流程需要兼顾运营的高效配置(零代码快速上线)商家海量商品提报的高性能强核验(零资损与冲突检测)客户端在极致高并发下的秒开率(性能与高可用)

关键业务与技术流程

会场搭建与提报的核心流程涉及招商选品、资损防范与可视化呈现三大阶段:

flowchart TD subgraph 招商选品阶段 ["1. 商家选品与提报校验 (招商控制)"] A[商家选择 SKU 并提报报名] --> B[第一层: 布谷鸟过滤器 - 快速过滤无重叠时空指纹] B -->|有重叠| C[第二层: 二维互斥 BitMap - 检查活动类型是否互斥] B -->|无重叠| F[进入价格核验流程] C -->|互斥且有重叠| D[第三层: 内存区间树 - 精准切片 SearchOverlap] C -->|可叠加| F D -->|冲突报警| E[驳回提报] D -->|无冲突| F end subgraph 资损防控与定价阶段 ["2. 最低价核验与历史价格追溯"] F --> G[MQ 实时投递影子订单实付价] H[Flink/Spark Streaming] -->|实时消费流统计| I[90天历史影子最低价] I -->|离线滚动并同步| J[营销中台选品缓存] F --> K{报名价校验: 是否触碰 90天影子最低价 90% 红线?} J --> K K -->|触碰红线/破产单| E K -->|安全放行| L[锁定活动状态 & 活动库存] end subgraph 会场渲染展现阶段 ["3. 可视化装修与高并发渲染"] L --> M[页面装修 Page Builder: 生成 Schema JSON] M --> N[数据静态化并推送到 CDN 边缘缓存] O[买家访问会场] --> P[CDN 快速吐出页面骨架与布局 Schema] P --> Q[异步动态拉取价格、库存与千人千面商品列表] end

运营招商与规则配置

会场搭建的前提是明确“卖什么”以及“怎么卖”:

会场选品与活动提报的核心技术瓶颈与解法

在高并发的大促招商场景下,面对千万级商品、错综复杂的优惠叠加规则以及极高频的商家批量提报,系统核心的技术瓶颈与工业级解法如下:

时空互斥与多维冲突检测

当商家提报大促会场时,系统必须在商家点击提交的瞬间,算出该 SKU 在活动期间的所有时间片内,各个已报名活动(如天天特价、店铺满减等)是否冲突,以及叠加后是否会产生规则冲突。

超高并发写热点与分布式锁排队

招商开启当天,海量商家会同时进行 Excel 批量导入,且同一个 SKU 可能会被频繁修改并重复提交。

底线价格红线与动态价格追溯

系统需要动态追溯该商品过去 30 天或 90 天内的历史最低价(包含各种满减券分摊后的真实影子实付价),确保提报价格绝对不跌破平台资损水位。

可视化会场装修 (Page Builder)

运营人员通过低代码可视化建站平台(装修系统)进行前端页面的组装:

静态与动态数据分离渲染 (Static-Dynamic Separation)

为了承载亿级 QPS 的访问,会场页面在架构上必须实施动静分离:

flowchart TD A[用户请求会场页面] --> B[CDN 边缘节点] B -->|1. 静态 HTML + 布局 JSON Schema| C[秒开渲染骨架] C -->|2. 异步拉取动态数据| D[API 网关 / 导购网关] D -->|个性化推荐| E[搜推广引擎 - 千人千面] D -->|营销价与库存| F[营销中台 & 库存中心] E & F --> G[动态数据拼装] G -->|返回客户端| C C --> H[完整页面呈现]

高可用与容灾降级策略

在大促瞬时洪峰下,保障会场可用性是第一红线:


营销计价引擎与价格计算逻辑

在电商交易系统(尤其是高度依赖各种拼团、大额满减、立减、跨店凑单的复杂场景)中,商品价格的计算绝对不是简单的“原价 - 优惠券”。为了扛住大促洪峰,营销中台的计价引擎必须是一套高性能、多级、动态且具备极致防资损能力的“流水线架构”

商品价格在全链路中,随着买家旅程的推进,主要分为静态读计价(高并发、多级缓存)提单写计价(高一致、底线熔断)。下面拆解营销中台是如何算出一件商品的最终价格的。

四层优惠金字塔(The Promotion Pyramid)

在营销中台的领域模型(DDD)中,优惠的计算遵循严格的顺位递进逻辑,绝对不允许平行乱序叠加,这被称为“四层优惠金字塔”:

     +---------------------------------------+
     |        第 4 层:支付优惠 (行立减)       |  <-- 支付中台控制(如指定支付渠道再减2元)
     +---------------------------------------+
     |      第 3 层:优惠券 (店铺/平台/跨店)   |  <-- 营销中台(买家主动领取的资产)
     +---------------------------------------+
     |    第 2 层:活动价 (拼团/秒杀/满折满减) |  <-- 营销中台(满足特定门槛自动触发)
     +---------------------------------------+
     |       第 1 层:商品基准价 (单品标价)    |  <--商品中心(商家填写的原价/SKU价)
     +---------------------------------------+

价格递进扣减公式

$$Price_{Final} = ((Price_{Base} - \Delta P_{单品}) - \Delta P_{活动}) - \Delta P_{优惠券} - \Delta P_{支付}$$

每一层计算出来的结果,作为下一层计算的“当前水位(Current Water Level)”。

核心计价流水线(Pipeline Architecture)

无论是商详页展示的“券后价”,还是购物车结算的“实付价”,营销中台的底层计价引擎(Pricing Engine)都采用 Pipeline(责任链)模式。每一次计价请求都会像传送带一样经历以下 5 个核心处理器:

[计价请求] -> [统一上下文构建] -> [活动最优解匹配] -> [优惠券多组合穷举] -> [影子溢出分摊] -> [底线价格熔断] -> [输出券后/实付价]

统一上下文构建 (Context Aggregator)

活动层最优解匹配 (Campaign Matcher)

优惠券最优组合推荐 (Coupon Optimization)

这是计价引擎里算法最硬核的部分。如果一个买家手里有 5 张店铺券、3 张平台券、4 张跨店满减券,如何找出最省钱的组合?

影子溢出分摊 (Proportional Shadow Allocation)

当多件商品合单结算(如跨店凑单),使用了一张“满 300 减 50”的平台券时,这 50 元不能均摊,必须采用按当前水位比例的影子分摊算法

底线价格熔断防资损 (Safety Sentinel)

两种业务场景下的高性能设计

在大促洪峰下,计价引擎面临的读写压力完全不同,必须分而治之:

导购/商详页(PDP)计价:极致读并发

确认订单/提交订单(Checkout)计价:极致强一致

计价小结

商品价格的计算,在微服务架构里是一个由粗到细、由快到准的过程:在导购页用多级缓存和静态预算追求高吞吐、高曝光;在提单页用责任链流水线、最优组合剪枝和底线防资损拦截追求绝对的资金安全。


Checkout 核心保障方案:柔性事务 vs. 刚性事务

在电商交易系统的结算确认(Checkout)阶段,面对高并发流量,如何保证“库存扣减、优惠核销、订单生成”的原子性与高可用,是核心设计难点。以下是两种主流架构设计方案的深度对比。

基于 Redis 与 Lua 的原子预扣减方案(AP 柔性事务)

这是目前主流互联网电商大厂在高并发大促场域(如秒杀、百亿补贴等)最常用的工业级标准解法。

核心思想

将高频的“计算与校验”操作前置到内存缓存中,将关系型数据库 MySQL 数据库异步化和削峰。提单核心流程被划分为两个阶段:

执行时序

sequenceDiagram autonumber actor Buyer as 买家前端 participant Order as 交易服务 (Order-Svc) participant MQ as 消息队列 (RocketMQ) participant Redis as 缓存集群 (Redis) participant DB as 订单数据库 (MySQL) Buyer->>Order: 提交订单 (携带 submitToken) Order->>Order: 防重校验 & 限流拦截 Order->>MQ: 发送事务 Half 消息 MQ-->>Order: 确认收到 Half 消息 Order->>Redis: 执行 Lua 脚本 (原子扣减库存与锁定优惠券) alt 缓存预扣成功 Redis-->>Order: 返回成功 (扣减后库存与券状态) Order->>DB: 开启本地事务 (写订单表、明细表、快照表等) alt 数据库落库成功 DB-->>Order: 事务提交成功 Order->>MQ: 提交(Commit)事务消息 Order-->>Buyer: 返回待支付状态与支付单号 else 数据库落库失败/超时 DB-->>Order: 事务回滚 Order->>MQ: 回滚(Rollback)事务消息 Order->>Redis: 异步补偿/回滚 Redis 库存与券 Order-->>Buyer: 返回提单失败 end else 缓存预扣失败/库存不足 Redis-->>Order: 返回库存不足/券失效 Order->>MQ: 回滚(Rollback)事务消息 Order-->>Buyer: 返回下单失败提示 end

防重试幂等与异步延迟核对机制

在 Checkout(提单)的高并发分布式链路中,调用缓存扣减库存和锁定优惠券可能会遭遇网络读超时(Read Timeout),此时状态处于**分布式网络三态(成功、失败、未知)**中的“未知”。

  1. 去程丢包:Redis 未收到请求,库存未扣减。
  2. 回程丢包:Redis 已执行扣减,但交易系统(Order-Svc)未收到响应。

如果在没有防资损设计下盲目重试,会导致重复扣减库存(引发少卖);若不处理直接报错,又会导致 Redis 中预扣减的库存或优惠券无法自动释放(引起死锁与资产流失)。

为解决该问题,大厂交易中台通常采用**“前置请求幂等化”“后置柔性回滚”**两套设计:

Lua 脚本内部引入订单幂等键(防去/回程丢包)

为了彻底消灭网络超时重试带来的重复扣减风险,Redis 中的扣减逻辑不能使用简单的 DECRBY,必须将扣减动作与订单的唯一幂等键(order_sn)进行深度绑定。

使用 Redis Hash 结构存储 SKU 级别的库存和单据核销状态:

-- KEYS[1] = {sku:12345}:stock_hash  (使用 Hashtag 确保同一 SKU 的路由在一台 Redis 分片)
-- ARGV[1] = order_sn (交易中台提单前预生成的全局唯一订单号)
-- ARGV[2] = buy_count (本次购买数量)

-- 1. 前置幂等校验:检查该订单号是否在此 SKU 上扣减过
local is_computed = redis.call('HEXISTS', KEYS[1], "order:" .. ARGV[1])
if is_computed == 1 then
    return 1 -- 证明是网络超时引起的重复请求,直接返回成功(1),不重复扣库存
end

-- 2. 库存充足校验
local current_stock = tonumber(redis.call('HGET', KEYS[1], "available_stock") or "0")
local buy_count = tonumber(ARGV[2])
if current_stock < buy_count then
    return -1 -- 库存不足
end

-- 3. 原子扣减并记录订单核销状态
redis.call('HSET', KEYS[1], "available_stock", current_stock - buy_count)
redis.call('HSET', KEYS[1], "order:" .. ARGV[1], buy_count) -- 记录扣减状态,用于防重与回滚

return 1 -- 首次扣减成功

网络超时的重试处理逻辑: 当交易服务(Order-Svc)调用 Redis 出现 Timeout 时,会携带原有的 order_sn 自动发起原单重试:

最终一致性与异步延迟队列核对(防整条链路崩溃)

如果网络不仅发生抖动,还出现了严重雪崩(例如 Redis 扣减成功,但交易系统在超时后还没来得及重试就宕机崩溃,导致后续写入 MySQL 订单库彻底放弃),被占用的 Redis 库存就会变成“无头尸体”。

为了防范此类的资损,需引入以 RocketMQ 延迟消息(或定时任务扫描)为核心的柔性事务保障机制:

sequenceDiagram autonumber participant Order as 交易系统 (Order-Svc) participant MQ as 消息队列 (RocketMQ) participant Redis as 缓存集群 (Redis) participant DB as 订单数据库 (MySQL) Order->>Order: 1. 预生成单号 order_sn Order->>MQ: 2. 发送延迟回查消息 (如 10 分钟延迟) Order->>Redis: 3. 调用 Lua 扣减库存与绑定订单号 Note over Order, Redis: 若此处发生严重网络超时/服务挂掉,导致主流程中断 Note over Order, DB: 10 分钟后,延迟消息到期触发消费 MQ->>Order: 4. 消费延迟消息 (携带 order_sn) Order->>DB: 5. 检查本地订单是否存在 DB-->>Order: 返回订单记录不存在 (判定提单失败) Order->>Redis: 6. 发起逆向补偿 (执行回退 Lua 脚本) Redis->>Redis: 7. 校验 order_sn 并回退库存,抹去单据痕迹

逆向回滚释放库存的 Lua 脚本

-- KEYS[1] = {sku:12345}:stock_hash
-- ARGV[1] = order_sn

-- 检查该订单号是否在 Redis 里占过坑
local lock_volume = tonumber(redis.call('HGET', KEYS[1], "order:" .. ARGV[1]) or "0")

if lock_volume > 0 then
    -- 确实占过坑,且后方没有生成实体订单,执行原子回退
    local current_stock = tonumber(redis.call('HGET', KEYS[1], "available_stock") or "0")
    redis.call('HSET', KEYS[1], "available_stock", current_stock + lock_volume)
    redis.call('HDEL', KEYS[1], "order:" .. ARGV[1]) -- 彻底抹去单据痕迹
    return 1 -- 回滚成功
else
    return 0 -- 没占过坑,无需回滚(对应去程就丢包的场景)
end
Redis Hash 结构防膨胀与 BigKey 规避策略

在高并发场景下,如果一个热销商品被疯狂下单,其对应的 SKU Hash Key 内部会塞入海量的单据流水(order_sn 对应的 Field )。若任由其无限制增长,会带来两大致命的风险:

  1. BigKey 灾难与 Redis 阻塞:当 Hash 内部的 Field 达到数万个时,Redis 会将底层编码从 ziplist/listpack 强行升级为 hashtable。此时若触发删除(如活动下线)或发生主从同步,大 Key 的释放与序列化会带来毫秒级的线程阻塞,拖垮 Redis 吞吐量。
  2. 内存溢出风险:如果一个超爆款商品面临十万级乃至百万级的无效/刷单重试请求,即使没有库存,这些单据流水也可能写入 Hash,瞬间榨干 Redis 内存。

在工业级实践中,需要配合以下三套**“防膨胀外挂刹车机制”**来保证系统的稳定性:

[!TIP] 高并发与资损防控设计小结 在分布式高并发的 Checkout 链路中,网络超时是必然会发生的常态。其核心设计原则是:「前台两段式重试防抖,后台异步延迟流兜底」。 首先,在前台同步操作层,通过将操作原子包裹在 Lua 脚本中,并加入基于 order_sn 的 Hash 幂等槽位,使得交易服务在面对 Redis 超时时,可以安全地发起原单 Retry,通过前置判重消灭“回程丢包”带来的重复扣减风险。 其次,在后台保障层,提单动作发起前外挂一枚 RocketMQ 的延迟核对消息。一旦主流程因为极端网络恶化、机器宕机导致本地 MySQL 事务中断,10 分钟后的延迟消费者会扮演“清道夫”角色,通过反查订单库并逆向驱动回滚 Lua 脚本,把 Redis 里预占的库存安全地“捞回来”,死守缓存与数据库的最终一致性红线。

异常回滚机制

异常场景自动处理与补偿方式
Redis 扣减成功,但本地 MySQL 写入失败/超时本地事务回滚,并向 RocketMQ 发送 Rollback 指令撤销半消息。对于网络超时等状态不明的极端场景,依靠“超时未支付延迟队列”(如 10 分钟超时)触发异步补偿,执行 Lua 脚本将 Redis 中的库存和优惠券状态安全恢复。
Redis 与 MySQL 均成功,但 Commit 消息在网络传输中丢失RocketMQ 具备自动“事务回查机制”。若 MQ 超过规定时间未收到 Commit/Rollback 指令,会主动回调 Order-Svc 的状态回查接口,检查对应的订单在 DB 中是否已存在。若存在则补发 Commit,否则补发 Rollback。
事务消息回查与补偿时序

为了应对 Commit/Rollback 消息丢失,或者交易服务忽然宕机导致状态不确定的边缘场景,RocketMQ 的“事务状态回查”机制提供了最终的一致性保障。以下是回查与补偿的具体交互流程:

sequenceDiagram autonumber participant MQ as 消息队列 (RocketMQ) participant Order as 交易服务 (Order-Svc) participant DB as 订单数据库 (MySQL) participant Redis as 缓存集群 (Redis) Note over MQ, Order: 场景 A:本地事务已提交,但 Commit 消息丢失/超时 MQ->>Order: 触发事务状态回查 (Check Transaction State) Order->>DB: 查询订单记录 (根据 submitToken/订单号) DB-->>Order: 订单记录存在 (已成功落库) Order->>MQ: 发送确认提交 (Commit) MQ->>MQ: 消息投递至业务 Topic,下游开始消费 Note over MQ, Order: 场景 B:本地事务未成功执行/已回滚,且 Rollback 消息丢失/未发送 MQ->>Order: 触发事务状态回查 (Check Transaction State) Order->>DB: 查询订单记录 (根据 submitToken/订单号) DB-->>Order: 订单记录不存在 Order->>MQ: 发送回滚指令 (Rollback) MQ->>MQ: 丢弃半消息 Order->>Redis: 异步执行 Lua 脚本进行库存/优惠券回滚补偿

基于分布式事务 2PC / Seata 方案(CP 刚性事务)

偏向传统的强一致性思维,通过事务管理器实现多个异构数据库的强原子性。

核心思想

营销系统的资产状态、库存系统的实物数据、交易系统的订单记录,必须在同一个全局分布式事务中要么全部成功,要么全部失败,任何时刻不允许出现状态不一致。

执行时序

sequenceDiagram autonumber participant Order as 交易服务 (Order-Svc) participant TC as 事务协调器 (Seata TC) participant Promo as 营销服务 (Promo-Svc) participant Stock as 库存服务 (Stock-Svc) Order->>TC: 开启全局分布式事务 (获取 XID) Order->>Order: 一阶段 Prepare: 写入本地订单数据 (不提交,持锁) Order->>Promo: RPC 调用: 核销优惠券 (透传 XID) Promo->>Promo: 一阶段 Prepare: 冻结优惠券 & 记录 Undo Log (不提交,持锁) Order->>Stock: RPC 调用: 预占实物库存 (透传 XID) Stock->>Stock: 一阶段 Prepare: 扣减库存行记录 & 记录 Undo Log (不提交,持锁) alt 所有分支均 Prepare 成功 Order->>TC: 汇报一阶段成功,请求全局提交 TC->>Promo: 广播全局提交 (异步清除 Undo Log) TC->>Stock: 广播全局提交 (异步清除 Undo Log) TC->>Order: 广播全局提交 (提交本地事务并释放锁) else 任一分支 Prepare 失败/超时 Order->>TC: 汇报失败,请求全局回滚 TC->>Promo: 广播全局回滚 (根据 Undo Log 反向补偿并回滚) TC->>Stock: 广播全局回滚 (根据 Undo Log 反向补偿并回滚) TC->>Order: 广播全局回滚 (回滚本地订单数据) end

异常回滚机制

在一阶段中,如果任意一个分支失败(例如由于库存不足导致扣减失败,或网络 RPC 超时),事务协调器 TC 就会向所有分支发送全局 Rollback 指令。各分支数据库根据本地保存的 undo_log 镜像(包含了修改前后的原始数据记录),逆向生成 UPDATE 语句执行,将数据库状态无损恢复至提单前的初始状态。

方案对比

对比维度Redis Lua + 事务消息 (AP 柔性)分布式事务 2PC / Seata AT (CP 刚性)
高并发读写性能极高(单机数十万 QPS 吞吐)。业务计算和状态校验完全在内存中完成,MySQL 数据库仅需接收异步削峰后的写入,极大地减轻了数据库压力。较低(受限于底层关系数据库连接池和行锁,通常在数千 QPS)。一阶段执行后不提交本地事务,数据库行锁一直被占用,大促时极易拖垮数据库。
数据一致性最终一致性。在 Redis 执行完毕到 MySQL 最终落库之间存在短暂的“不一致窗口”,需要依赖延迟消息和异步补偿机制保证最终一致。强一致性。基于传统的两阶段提交控制,数据在事务边界内保持严格一致,无中间的不确定状态。
存储系统开销极低。对磁盘 I/O 极其友好,消除了分布式事务带来的大量事务日志和数据镜像写入。极高。每一次数据库写操作,Seata 都需要在本地数据库生成、写入并刷盘大量的 undo_log,造成磁盘 I/O 成为严重瓶颈。
研发维护成本较高。需要开发人员自行设计并实现精密的 Lua 脚本以及各种异常分支下的异步回滚与对账逻辑。极低。框架对业务代码几乎无侵入,开发人员仅需配置全局事务注解即可,系统自动实现二阶段的提交与回滚。
适用场域电商前台核心黄金交易链路(如商详页、购物车、秒杀及大促提单)。中后台、非黄金链路(如商家供应链补货、跨境履约关税计算、财务记账、ERP 系统)。

选型总结

在电商前台核心下单链路上,业界主流架构坚定选择 “Redis + Lua 预扣 + 事务消息” 的柔性事务方案。这是因为电商核心交易系统的设计哲学是 “以响应时间(RT)为红线,拿吞吐量换可用性,靠延迟消息与对账保最终一致”。 若采用 CP 刚性事务方案,大促瞬间几十万笔订单抢购同一个热点 SKU 时,所有事务都会并发在 MySQL 对应的商品行记录上争抢行锁,导致数据库连接池迅速被占满,响应时间飙升,最终引发整站服务的雪崩。而 Redis Lua 方案将高并发下的串行扣减压力安全地卸载到 Redis 的内存操作中,后端利用消息队列细水长流地进行订单落库与拆单履约,在保障高可用的同时确保资损为零。


核心系统能力清单


关键设计原则


交易状态主线

stateDiagram-v2 [*] --> 待支付: 用户下单 (创建待支付单) 待支付 --> 已关闭: 超时自动关单 / 用户主动取消 (释放预占资源) 待支付 --> 已支付: 支付成功回调 已支付 --> 待发货: 触发履约路由 待发货 --> 已发货: 仓库拣货打包出库 已发货 --> 已签收: 物流妥投确认 已签收 --> 已完成: 确认收货 / 过售后期 已支付 --> 退款中: 用户发起退款/退货售后 待发货 --> 退款中: 用户发起退款/退货售后 已发货 --> 退款中: 用户发起退款/退货售后 退款中 --> 已退款: 售后审核通过 & 原路退款成功

支付状态与物流状态:解耦设计与聚合展示

在现代大型分布式交易系统中,支付状态机和物流履约状态机通常是两套完全独立的系统。它们各自聚焦不同的业务领域,再由订单域进行状态聚合,向用户和客服展示统一的订单展示状态。

状态机解耦的必要性

支付域状态机

stateDiagram-v2 [*] --> PAYMENT_PENDING: 创建支付单 PAYMENT_PENDING --> PAYING: 用户唤起支付收银台 PAYING --> PAY_SUCCESS: 支付网关成功回调 (异步/同步通知) PAYING --> PAY_FAILED: 支付网关失败通知 / 扣款失败 PAYMENT_PENDING --> PAY_CLOSED: 交易超时关闭 / 用户取消订单 PAY_FAILED --> PAYING: 用户重新尝试支付

支付状态定义

当前状态 (Code)状态含义触发事件 / 动作下一状态 (Code)
PAYMENT_PENDING待支付(订单创建)用户唤起支付收银台PAYING
PAYMENT_PENDING待支付(订单创建)支付超时或用户主动取消订单PAY_CLOSED
PAYING支付中(渠道处理中)支付网关成功回调(网关异步/同步通知)PAY_SUCCESS
PAYING支付中(渠道处理中)支付网关失败通知或扣款失败PAY_FAILED
PAY_FAILED支付失败(可重试)用户更换支付通道并重新发起支付PAYING
PAY_SUCCESS支付成功(终态)资金已确认到账,不可逆终态
PAY_CLOSED支付关闭(终态)支付单失效,不再接受支付请求终态

物流履约域状态机

stateDiagram-v2 [*] --> FULFILL_PENDING: 订单已支付,入履约系统 FULFILL_PENDING --> WAREHOUSE_PICKING: 履约路由/分仓成功,进入仓内拣货 WAREHOUSE_PICKING --> WAREHOUSE_SHIPPED: 仓库出库完成,打印面单 WAREHOUSE_SHIPPED --> IN_TRANSIT: 承运商揽收扫描,包裹在途 IN_TRANSIT --> DELIVERED: 快递员妥投签收 IN_TRANSIT --> TRANSIT_EXCEPTION: 丢件、破损或超期延误 TRANSIT_EXCEPTION --> IN_TRANSIT: 异常处理完毕,重新派送 TRANSIT_EXCEPTION --> REVERSE_FLOW: 拒收回流或异常拦截退回

物流履约状态定义

当前状态 (Code)状态含义触发事件 / 动作下一状态 (Code)
FULFILL_PENDING待履约履约路由运行,成功下发分仓WAREHOUSE_PICKING
WAREHOUSE_PICKING仓内拣货中仓库打包、贴单并完成出库扫描WAREHOUSE_SHIPPED
WAREHOUSE_SHIPPED已出库快递物流承运商上门揽收并扫描建包IN_TRANSIT
IN_TRANSIT运输派送中快递妥投投递,客户签收确认DELIVERED
IN_TRANSIT运输派送中检测到包裹长时停滞、破损或丢件TRANSIT_EXCEPTION
TRANSIT_EXCEPTION运输异常异常件理赔或重置路线重新派送成功IN_TRANSIT
TRANSIT_EXCEPTION运输异常客户拒签或触发中途地址拦截回流REVERSE_FLOW
DELIVERED已妥投(终态)客户正常签收,正向履约结束终态
REVERSE_FLOW逆向退回(终态)商品退回仓库完成质检与入库终态

订单域的聚合状态映射

为了保证系统底层解耦的同时兼顾前端极佳的用户体验,订单中心设计了“子状态多字段存储,显示状态实时计算”的方案:

常见聚合映射规则

支付状态 (PaymentState)履约状态 (FulfillmentState)售后状态 (AfterSaleState)聚合订单展示状态 (DisplayState)业务场景解释
PAYMENT_PENDING--待付款订单已创建,等待用户在时效内支付
PAY_CLOSED--已关闭超时未付或主动取消,订单已失效
PAY_SUCCESSFULFILL_PENDING / WAREHOUSE_PICKING-待发货资金已确认,仓库正在准备拣货发货
PAY_SUCCESSWAREHOUSE_SHIPPED / IN_TRANSIT-待收货 / 运输中商品已离仓发出,正由快递公司派送中
PAY_SUCCESSDELIVERED-已完成用户已签收,进入常规评价或完成态
PAY_SUCCESSTRANSIT_EXCEPTION-配送异常包裹运输途中遇到丢件、延误等问题,需要平台干预
PAY_SUCCESS-REFUNDING退款中 / 售后中无论处于哪种履约阶段,用户发起了退款/退货申请
PAY_SUCCESS-REFUNDED已退款 / 交易关闭售后审核通过,资金已原路退回至用户账户

跨域状态一致性保障


后续演进与高级专题

在理清上述电商核心交易主链路与核心状态机后,如需对系统设计进行更深层次的探究,建议围绕以下高风险与大规模并发专题展开: