Skip to content

电商平台 架构模板

代表产品:Amazon、Shopify、淘宝、各类在线零售与交易平台 一句话定位:在海量并发下,让「钱货两清」这件事绝不出错,还要扛得住大促那一波洪峰。


1. 一句话定位

一个电商平台 = 一台「读多写少、读可凑合、写必须分毫不差」的交易机器 + 一套专门用来扛大促洪峰的削峰装置

架构上最反直觉的一点:它和普通网站最大的不同,不是页面多,而是这里同时存在两种截然相反的数据。逛商品、看推荐、读评价——这些是海量的读,慢一点、旧一点都没人追究;但扣库存、下订单、付钱——这些写一旦错了,就是少卖了钱、超卖了货、重复扣了款,是要赔钱、要打官司的。整套架构的核心命题,就是**「把这两种数据用完全不同的强度去对待」**:对钱和库存锱铢必较,对浏览和推荐网开一面。

2. 业务本质:它在解决什么问题

平台要做的事,说白了就一句:让买家能放心地把钱交出来、让卖家能准确地把货发出去,中间一分钱、一件货都不能错。

它的业务现实带来三条铁律:

  • 钱货必须两清,且能对账:用户付了钱就必须有货、有订单;平台收了钱就必须能和支付方对得上账。这里没有「最终大概一致」的余地。
  • 库存是有限的、会争抢的:最后一件商品不能同时卖给两个人(超卖),否则就是必然的客诉和赔付。
  • 流量极不均匀,大促是常态:平时风平浪静,一到大促/秒杀,瞬时流量可以涨几十上百倍,系统要么扛住、要么崩盘上新闻。

关键事实:在电商里,「读错了」用户骂两句,「写错了」平台真金白银地赔。 这一条决定了后面几乎所有架构取舍——尤其是「为什么不能用一个大事务把整个下单流程串起来」。

3. 核心需求与约束

把需求拆成两类。区分「功能」和「质量」是架构师的第一基本功。

功能性需求(系统要能做什么):

  • [ ] 浏览与搜索:逛商品目录、搜关键词、看推荐和评价。
  • [ ] 购物车:加购、改数量、结算。
  • [ ] 下单:校验、扣库存、生成订单。
  • [ ] 支付:发起支付、确认收款、失败回滚。
  • [ ] 库存管理:扣减、回补、防超卖。
  • [ ] 履约/物流:发货、跟踪、签收。
  • [ ] 价格与促销:定价、优惠券、满减、秒杀价。
  • [ ] 用户与账户:登录、地址、订单历史。

非功能性需求 / 质量属性(这才是架构的主战场):

质量属性目标为什么对这类系统重要
资金强一致100% 正确、可对账钱算错一分都是事故;支付与账务必须经得起逐笔核对。
库存正确性绝不超卖卖出去发不出货,是必然的客诉和赔偿。
浏览延迟商品/搜索页快速返回逛得不顺手,用户直接关页走人,转化率下降。
峰值吞吐扛住大促数十倍洪峰大促当天崩了,是直接的销售损失和品牌事故。
可用性核心交易链路高可用下单付款挂了,等于停业。

关键约束(不可逾越的边界):

  • 🔴 不同数据要用不同强度的一致性。这是头号设计原则:钱和库存要强一致,浏览和推荐可以最终一致。混为一谈,要么慢死,要么出错。
  • 🔴 库存的「最后一件」是天然的争抢点。热点商品的单行库存会被无数请求同时抢,这是绕不开的物理瓶颈。
  • 🔴 大促洪峰不可预测又极端,系统必须能削峰、能限流、能降级,而不是硬扛到崩。
  • 🔴 一切涉及钱的操作必须幂等:网络会重试、用户会狂点按钮,绝不能因此重复下单、重复扣款。

4. 架构全景图

                                   用户(Web / App)

                          ┌─────────────▼─────────────┐
                          │   接入层:网关 / CDN        │  鉴权、限流、削峰、降级
                          └─────────────┬─────────────┘

         ┌──────────────── 读路径(读多,重缓存)─┴─ 写路径(写少,要强一致)──────────┐
         │                                                                          │
         ▼                                                                          ▼
┌────────────────┐  ┌──────────┐  ┌──────────┐                          ┌────────────────────┐
│  商品目录服务    │  │  搜索     │  │  推荐     │                          │     购物车服务       │
│ (海量读,缓存)  │  │ (专用引擎)│  │ (最终一致)│                          └─────────┬──────────┘
└───────┬────────┘  └──────────┘  └──────────┘                                    │ 结算
        │ 多级缓存                                                                 ▼
        ▼                                                          ┌──────────────────────────┐
┌────────────────┐                                                 │  下单编排(Saga 协调者)    │
│  内存级 KV 缓存  │  ◀── 缓存预热                                    │  一步步推进,失败按步回滚    │
└────────────────┘                                                 └───┬────────┬─────────┬───┘
                                                                       │        │         │
                          ┌──── 削峰填谷:异步下单队列 ─────────────────┘        │         │
                          │                                                     ▼         ▼
                          ▼                                          ┌──────────┐  ┌──────────┐
                  ┌──────────────┐      ┌──────────────┐             │ 订单服务  │  │ 支付服务  │
                  │  库存服务      │      │  价格/促销     │             │(状态机)  │  │(强一致)  │
                  │ 防超卖/分段库存│      └──────────────┘             └────┬─────┘  └────┬─────┘
                  └──────────────┘                                        │             │
                                                                          ▼             ▼
                                                          ┌──────────────────┐  ┌──────────────┐
                                                          │   履约 / 物流      │  │  对账系统      │
                                                          │ (发货、跟踪)      │  │ (逐笔核对)    │
                                                          └──────────────────┘  └──────────────┘

灵魂部件是右侧那条写路径:下单编排 → 库存 → 订单 → 支付。左边的浏览/搜索/推荐再大,本质都是「读」,可以靠缓存横向堆机器解决;真正难、真正不能错的,是这条又要正确、又要扛洪峰的交易链路。

5. 组件职责

逐个说明上图里每个关键部件做什么 + 为什么需要它(没有「为什么」的部件就是过度设计)。

  • 接入层(网关 / CDN):鉴权、限流、把静态资源和图片推到边缘,大促时承担削峰和降级的第一道闸。为什么需要:洪峰必须在最外层就被整形和拦截,别让它直接砸到核心服务。
  • 商品目录服务:管理商品信息,读极多、写极少,靠多级缓存扛量。为什么需要:逛商品是流量最大的入口,必须用缓存把数据库护在后面。
  • 搜索:用专用的搜索系统支持关键词、筛选、排序。为什么需要:商品搜索是「按内容找」,这是通用数据库做不好的,需要专门的倒排索引能力。
  • 推荐:基于行为算「你可能想买」,可以最终一致、可以略旧为什么需要:提升转化,但它本质是「锦上添花」,慢一点、旧一点不影响钱货。
  • 购物车服务:暂存用户想买的东西,直到结算。为什么需要:加购到下单之间有时间差,需要一个轻量、可快速读写的暂存区。
  • 下单编排(Saga 协调者):把「扣库存 → 创建订单 → 调支付 → 确认/回滚」这一串步骤按顺序推进,任一步失败就按相反顺序补偿回滚为什么需要:下单跨多个服务,又不能用一个大事务锁住全部(太重、扛不住量),所以用 Saga 把它拆成「可逐步推进、可逐步回滚」的长流程。
  • 库存服务:扣减、回补库存,死守不超卖;对热点商品用分段库存或排队化解争抢。为什么需要:库存是钱货两清的物理前提,超卖直接等于赔付。
  • 订单服务:维护订单的状态机(待支付 → 已支付 → 已发货 → 已完成 / 已取消 / 已退款),保证状态只能合法流转。为什么需要:订单是交易的「事实凭证」,它的每一次状态变化都要可追溯、不可乱跳。
  • 支付服务:对接资金,强一致 + 幂等,确保「钱只扣一次、且和订单对得上」。为什么需要:这是整条链路上最不能错的环节,任何重复或丢失都是资损。
  • 价格 / 促销:计算最终成交价(原价、优惠券、满减、秒杀价)。为什么需要:价格涉及钱,且促销规则多变,需要集中、可审计地算。
  • 履约 / 物流:订单确认后安排发货、提供物流跟踪。为什么需要:把「线上成交」落地成「线下到货」,且这部分天然是异步的。
  • 对账系统:逐笔核对订单、支付、账务,发现并修复不一致。为什么需要:既然交易链路用了「最终一致」(Saga),就必须有一套兜底机制来保证最终真的一致——对账是资金安全的最后防线。

6. 关键数据流

挑 3 个最能体现这个系统特点的场景。

场景一:浏览到加购(读多、重缓存的路径)

1. 用户逛首页/类目 ──▶ 网关 ──▶ 商品目录服务
2. 先查【内存级 KV 缓存】── 命中 ──▶ 直接返回(绝大多数请求走这里)
                        └ 未命中 ─▶ 回源数据库 ─▶ 结果写回缓存 ─▶ 返回
3. 搜索关键词 ──▶ 专用搜索引擎(倒排索引)返回结果
4. 页面上的「猜你喜欢」──▶ 推荐服务(数据可略旧,最终一致即可)
5. 用户点「加入购物车」──▶ 购物车服务暂存

注意:这一整条路径几乎不碰核心数据库的写,全靠缓存和专用引擎扛量。逛得越多,缓存价值越大。这是「读可凑合」的体现——数据旧几秒、推荐不那么准,都无所谓。

场景二:下单(写路径,Saga 一步步推进、失败就回滚)

用户点「提交订单」──▶ 下单编排(Saga 协调者)启动:

  步骤① 扣库存 ──▶ 库存服务:预扣成功?
        ├─ 失败(没货了)──▶ 直接结束,告诉用户「已售罄」
        └─ 成功 ─▶ 继续
  步骤② 创建订单 ──▶ 订单服务:生成订单,状态=「待支付」
        └─ 失败 ─▶ 补偿:回补步骤①扣掉的库存 ──▶ 结束
  步骤③ 调支付 ──▶ 支付服务:发起扣款(幂等,带唯一下单号)
        ├─ 成功 ─▶ 订单状态→「已支付」,预扣库存转为正式扣减 ──▶ 触发履约
        └─ 失败/超时 ─▶ 补偿:订单→「已取消」,回补库存 ──▶ 结束

  ★ 每一步都可独立重试;失败时按【相反顺序】补偿。全程没有一个横跨所有服务的大事务。

架构要点:用「可补偿的长流程(Saga)」替代「一个大分布式事务」。 大事务会长时间锁住库存、订单、支付,在高并发下直接把系统拖垮;Saga 把它拆成「每步快进快出、错了再退回」,用最终一致 + 对账换来了吞吐。

场景三:大促秒杀(削峰填谷 + 排队 + 限流)

百万人同时抢 1000 件 ──▶ 网关【限流】:大部分请求在门口就被挡掉/排号
        │ 放进来的请求

  异步下单队列(削峰填谷)──▶ 把瞬时洪峰摊平成系统能消化的稳定速率
        │ 逐个出队

  库存服务:对这件热点商品做【分段库存 / 排队扣减】,把单行争抢打散
        │ 抢到的

  正常走 Saga 下单流程;没抢到的 ──▶ 立刻返回「已抢光」(快速失败,别让它干等)

架构要点:洪峰不要硬扛,要「整形」。 限流在门口拦、队列在中间摊平、分段库存在底层散热、降级在崩溃前丢车保帅——四件套合力,把「几十倍的尖峰」变成「系统能稳稳消化的水流」。

7. 数据模型与存储选择

核心实体:商品库存(SKU 维度);用户购物车订单订单项;订单支付单;促销/价格规则。其中订单带状态机,支付单账务流水是资金对账的依据。

数据存储类型为什么
订单 / 支付 / 账务流水关系型(强事务)涉及钱,要强一致、要事务、要能逐笔对账
库存(可扣减计数)支持原子扣减的强一致存储防超卖靠原子操作;热点项再做分段
商品目录(海量读)关系型为底 + 内存级 KV 缓存读极多写极少,缓存挡住绝大部分读
搜索索引专用搜索系统(倒排索引)「按内容找」是通用数据库做不好的
购物车内存级 KV 缓存(可持久化)读写频繁、结构简单、对一致性要求不高
推荐结果预计算 + 缓存可最终一致、可略旧,不该实时压数据库
商品图片对象存储 + CDN大、不变、按引用取,推到边缘加速
大促削峰异步消息队列把瞬时洪峰摊平成可消化的稳定速率

教学点(本节最重要):一致性不是「全局开关」,而是「按数据分级的拨盘」。 钱拨到「强一致 + 可对账」,库存拨到「防超卖」,而浏览、推荐、评价大可拨到「最终一致」。用一种强度去要求所有数据,不是慢死就是出错——这正是电商架构的精髓。

8. 关键架构决策与权衡 ⭐

(本模板最值钱的一节。) 电商的每个岔路口,几乎都在回答同一个问题:「这块数据该用多强的一致性,以及怎么在洪峰下还不出错」。

决策 1:库存怎么扣才不超卖?

  • 悲观锁(扣之前先锁住这行):绝对不超卖,但高并发下大家排队抢同一把锁,热点商品直接锁成瓶颈,吞吐崩塌。
  • 乐观锁(带版本号扣,冲突就重试):无锁、吞吐高,但热点商品冲突率极高,大量请求反复重试,同样拖慢。
  • 预扣 + 异步确认(先快速预占,支付成功再转正式扣减,超时未付就回补):响应快、能扛量,代价是要管理「预占超时回补」的复杂逻辑。
  • 分段库存(把 1000 件拆成 10 段各 100 件,请求被分散到不同段上扣):把「单行争抢」打散成「多行并行」,极大缓解热点。代价是分段间可能不均(有的段空了有的还剩),需要再平衡。
  • 取向:普通商品用乐观锁/原子扣减足矣;热点/秒杀商品上「预扣 + 分段 + 排队」组合拳。 核心思想是把一个被疯抢的点,变成多个可并行的点。代价是复杂度和「预占回补」的运维成本,但这是热点不超卖的唯一出路。

决策 2:订单与支付的一致性——分布式事务,还是 Saga + 对账?

  • 分布式事务(两阶段提交那一类):语义最干净,要么全成功要么全失败。但它会长时间锁住多个服务的资源,在高并发下吞吐极低、一个参与方卡住就全卡住,电商扛不起
  • Saga + 最终一致 + 对账:把下单拆成「扣库存→建单→支付」一串可补偿步骤,每步快进快出,失败按相反顺序回滚,再用对账系统兜底保证最终一致。
  • 取向:几乎一定选 Saga + 对账。 用「最终一致 + 一套靠谱的对账」换来了高吞吐。代价是中间会短暂出现「不一致窗口」(订单已建但还没支付),以及必须额外建设对账系统这条资金安全的最后防线——这笔投入省不得。

决策 3:幂等设计——怎么防重复下单 / 重复支付?

  • 不做幂等:网络一重试、用户手一抖连点两下,就重复创建订单、重复扣款,直接资损。
  • 做幂等:每个下单/支付请求带一个唯一标识(幂等键),服务端发现重复的同一个键,直接返回上次的结果而不再执行一遍。
  • 取向:凡是涉及钱和库存的写操作,必须幂等,没有例外。 因为重试在分布式系统里是常态(超时了不知道成没成,只能重发)。代价是要维护幂等键的存储和去重逻辑,但相比资损,这点成本微不足道。

决策 4:读写分离——浏览的海量读和交易的关键写要不要分开?

  • 不分:读写都压在同一套库上,海量的浏览读会和关键的交易写抢资源,互相拖累。
  • 分:把读(目录、搜索、推荐)用缓存和只读副本扛起来,把写(库存、订单、支付)留给强一致的主存储。
  • 取向:必分。 读和写在电商里是「两种物种」——读求快求廉价、写求准求一致。把读路径用缓存和专用引擎托管,让主存储专心伺候不能错的写。 代价是读到的数据可能略有延迟(最终一致),但浏览场景完全可以接受。

决策 5:大促洪峰怎么扛?

  • 硬扛(无脑加机器):成本极高,且加机器有上限,数据库这种有状态部件没法无限扩,到点还是会崩
  • 整形(削峰填谷 + 限流 + 降级 + 缓存预热):用队列把尖峰摊平、用限流在门口拦、用降级在危急时丢掉非核心功能、提前把热点数据预热进缓存。
  • 取向:洪峰要「整形」,不要「硬扛」。 大促前缓存预热(把爆款数据提前灌进缓存)、入口限流(超过容量就排队或快速失败)、核心链路用异步队列削峰、危急时降级(暂时关掉推荐/评价等非核心功能,保住下单付款)。代价是体验有损(排队、功能临时缩水),但这是「保住核心交易」对「全崩」的明智取舍。

决策 6:订单状态——用状态机管理,还是散落各处改字段?

  • 散落改:哪儿方便就在哪儿改订单状态。简单,但状态会乱跳(比如从「已退款」又跳回「已发货」),难追溯、易出 bug。
  • 状态机:明确定义「哪些状态、允许哪些流转」,任何非法跳转一律拒绝。
  • 取向:订单必须用状态机。 它是交易的事实凭证,每一次状态变化都要合法、可追溯。代价是前期要把状态和流转规则设计清楚,但这换来的是整个交易生命周期的可控与可审计。

9. 规模化与瓶颈

电商的瓶颈很有规律:先卡在「热点的写」,再卡在「洪峰的量」,最后卡在「读的成本」。

  • 第一个瓶颈:热点商品的单行库存争抢。 爆款的「最后那批货」被无数请求同时抢同一行,锁竞争把吞吐打到地板。 破解:① 分段库存,把一行拆成多段并行扣;② 排队化,让抢同一商品的请求排队顺序处理;③ 预扣 + 异步确认,缩短每个请求占用的时间;④ 热点识别 + 单独扩容。
  • 第二个瓶颈:大促洪峰。 瞬时流量几十倍,同步下单会把链路顶穿。 破解:① 异步下单(请求先入队,快速给用户「排队中/已受理」);② 队列削峰填谷,把尖峰摊平;③ 入口限流,超容量就快速失败别干等;④ 降级,危急时砍掉非核心功能保核心;⑤ 缓存预热,别让冷缓存在峰值回源压垮数据库。
  • 第三个瓶颈:目录与搜索的海量读。 浏览流量最大,直接压数据库必崩。 破解:① 多级缓存(边缘/CDN + 内存级 KV),把绝大多数读挡在数据库前;② 搜索交给专用搜索系统,别用通用数据库硬搜;③ 读写分离,只读副本扛读。
  • 第四个瓶颈:一致性窗口带来的对账压力。 用了 Saga/最终一致后,会持续产生少量「订单、支付、账务对不上」的情况。 破解:建设对账系统,逐笔核对、自动修复能修的、报警人工处理修不了的——这是规模化后资金安全的常态化基础设施。

10. 安全与合规要点

  • 🔴 支付安全是头等大事。 资金链路要强一致、可审计、逐笔可对账;敏感支付信息按合规要求处理,核心扣款判断绝不放在客户端。
  • 幂等即安全:重复请求不能造成重复扣款/重复发货——前面说的幂等键,既是正确性手段,也是防资损的安全手段。
  • 价格篡改防护:成交价必须由服务端重新计算,绝不能信任客户端传来的价格;否则会被人改包以一分钱下单。
  • 防刷 / 防黄牛:大促秒杀会招来脚本和黄牛,需要风控(限购、人机校验、行为识别)在入口拦截异常流量,既保公平也保护库存和系统。
  • 服务端不信任客户端:库存、价格、优惠资格、下单权限,全部以服务端判定为准。客户端传来的一切都可能被篡改。
  • 超卖即事故:库存的原子性和防超卖,既是正确性问题,也是「卖了发不出货」的合规与信誉风险。

11. 常见误区 / 反模式

  • 用一个大事务把『扣库存→建单→支付→发货』整串串起来 → ✅ 拆成可补偿的 Saga 长流程,每步快进快出,失败按相反顺序回滚。
  • 下单时同步调支付,卡着等支付方回话 → ✅ 支付异步化、幂等化,别让一次外部调用把整条链路堵死。
  • 不做幂等,网络重试/用户连点就重复下单、重复扣款 → ✅ 涉及钱货的写操作一律带幂等键去重。
  • 库存直接 UPDATE 库存 = 库存 - 1 硬扣 → ✅ 用原子扣减 + 防超卖;热点商品上分段/排队,别让单行变成锁竞争的瓶颈。
  • 用同一种强一致性要求所有数据(连推荐、评价都要求实时一致) → ✅ 按数据分级:钱强一致、库存防超卖、浏览/推荐最终一致。
  • 大促靠无脑加机器硬扛 → ✅ 削峰填谷 + 限流 + 降级 + 缓存预热,把洪峰「整形」而不是「硬接」。
  • 信任客户端传来的价格/库存/优惠 → ✅ 一切金额和资格由服务端重新核算。
  • 用了最终一致却不建对账 → ✅ 最终一致必须配对账兜底,否则「最终」可能永远到不了。

12. 演进路线:MVP → 成长期 → 成熟期

架构是会长大的。别拿成熟期的图去套 MVP。

阶段用户/规模量级架构长什么样此时该操心什么
MVP验证想法单体商城:商品、购物车、订单、支付都在一个应用里,一个数据库,下单可能就是一个事务搞定先验证「这门生意跑不跑得通」,别一上来就拆微服务、上 Saga
成长期万~百万订单拆出核心域(库存 / 订单 / 支付独立),引入缓存挡读、专用搜索系统、读写分离;下单改用 Saga + 幂等找瓶颈、保住交易正确性,把读路径用缓存撑起来
成熟期千万级以上 / 有大促大促专项:分段库存、异步下单 + 削峰队列、限流降级、缓存预热;建设对账系统;关键链路多活容灾库存防超卖、洪峰削峰、资金对账、容灾、跨团队协同

13. 可复用要点

  • 💡 一致性是「按数据分级的拨盘」,不是「全局开关」。 先问每块数据「错了/旧了会怎样」,再决定给它多强的一致性。这条思想适用于任何「读写诉求差异巨大」的系统。
  • 💡 别用一个大事务串长流程,用「可补偿的长流程 + 对账」。 跨多个服务、又扛高并发时,最终一致 + 兜底校验,几乎总是比分布式大事务更现实。
  • 💡 把『被疯抢的一个点』变成『可并行的多个点』。 分段库存的思想,可推广到任何热点争抢场景——分片、分桶、排队,本质都是「给热点散热」。
  • 💡 洪峰要『整形』,不要『硬扛』。 限流、排队、削峰、降级是一套通用的「流量整形」工具,任何会遇到尖峰的系统都用得上。
  • 💡 凡是会被重试的写操作,都要幂等。 在分布式世界里重试是常态,幂等是保证「重试不闯祸」的通用纪律——尤其是任何碰钱的地方。

🎯 随堂检验

🤔高并发下防止超卖,最关键的手段是?
  • A多加几台服务器硬扛
  • B对库存做原子扣减,而非「读余量-减余量-写回」
  • C把库存数字放进缓存

参考原型与延伸阅读

本模板基于以下权威模式库官方工程文档整理。

📖 模式 / 工程文档:


📌 一句话记住电商平台:它不是「商品很多的网站」,而是「一台钱货不能错、还要扛得住洪峰的交易机器」——所有架构取舍,最终都在回答『这块数据该多较真,以及大促那天它崩不崩』。