首页 / 知识库 / python服务端进阶 / 后端微服务架构

08 - 完整例子:一次”下单”的旅程

前面七章的概念,都是零散的零件。这一章我们用一个动作——用户点”提交订单”,把它们全串起来,看一个请求在微服务系统里到底怎么流转。

只讲思路,不写代码。看完你脑子里应该能”放电影”一样过一遍整个流程。

场景设定

张三在 App 里选好了一件商品,点击**“提交订单”**。这一下背后,涉及好几个服务:

  • 用户服务:他是谁、是不是 VIP
  • 商品服务:这件商品还有没有库存
  • 订单服务:生成一笔订单
  • 支付服务:发起支付
  • 通知服务:下单成功后发个通知

第一幕:请求进门(网关)

张三点"提交订单"


┌──────────────┐
│  API 网关      │  ① 检查张三登录了没(鉴权)——回顾第06章
│              │  ② 没被限流的话,放行
│              │  ③ 看出这是下单请求,转发给【订单服务】
└──────┬───────┘

    订单服务

客户端只跟网关说话,网关做完鉴权、限流,把请求丢给订单服务。张三不需要知道订单服务在哪台机器上。

第二幕:下单前的核对(同步调用)

订单服务接到请求,下单前得先确认两件事,这两件都必须立刻知道结果,所以用同步调用(第 04 章的”打电话”):

订单服务

   │  ① "用户 42 是 VIP 吗?"(要算折扣)
   │  ─── 同步调用 ──▶ 用户服务 ──▶ 用户库 ──▶ "是 VIP"
   │  ◀──────────────────────────────────

   │  ② "商品 99 还有货吗?"
   │  ─── 同步调用 ──▶ 商品服务 ──▶ 商品库 ──▶ "还剩 5 件"
   │  ◀──────────────────────────────────


 两个都 OK,可以下单了

注意:订单服务并没有直接去查用户库、商品库(第 05 章铁律:不许直连别人的库),而是通过接口去”问”对方服务。至于对方现在在哪台机器——靠服务发现(第 06 章”通讯录”)找到。

第三幕:创建订单 + 扣库存(跨服务一致性)

这是最微妙的一步,涉及两个库:订单库要加一条订单,商品库要减一件库存。它们没法用一个事务包住(第 05 章的难题)。处理思路:

订单服务
   │  ① 先在自己的【订单库】创建订单,状态 = "待支付"
   │     (自己库里的事,稳)

   │  ② 往【消息队列】丢一条消息:"订单已创建,请扣减商品99的库存"
   │     (异步,第04章的"发微信";丢完就继续)

消息队列  ────────▶  商品服务
                      │  ③ 取到消息,把商品99库存 5 → 4
                      └─ 扣成功 ✅

万一第 ③ 步扣库存失败了(比如刚好被别人抢光)?就走补偿(第 05 章):商品服务发一条”扣减失败”事件,订单服务收到后把这笔订单改成”已取消”。最终,数据一定会对上——这就是最终一致性。

第四幕:发起支付(同步)

订单创建好了,接着叫支付服务干活:

订单服务  ─── 同步调用 ──▶ 支付服务
                            │  生成支付单,返回一个支付链接/二维码
订单服务  ◀──────────────────


把支付信息返回给网关 → 返回给张三的 App

张三的 App 这时就能显示”请扫码支付”了。注意:到这里,主流程已经很快地回给用户了,后面那些不紧急的事,都交给异步。

第五幕:下单成功的”善后”(异步,不占用户时间)

下单成功这件事,还牵扯一堆”通知类”的后续动作,但它们都不用让张三等,所以全走消息队列(异步、解耦、削峰——正是消息队列的意义):

订单服务丢一条"订单已创建"事件到消息队列

     ┌──────────────┼──────────────┐
     ▼              ▼              ▼
  通知服务        积分服务        数据分析服务
  发下单短信      给张三加积分    记录一条销售数据
 (各干各的,慢慢处理,谁挂了都不影响下单本身)

第六幕:全程有人”盯着”(追踪与监控)

从第一幕到现在,这个请求跨了网关、订单、用户、商品、支付好几个服务。整条链路上,每一步都带着同一个追踪号记日志(第 06 章链路追踪)。所以万一张三反馈”下单卡了 5 秒”,运维用这个追踪号一查,立刻能看出是哪一环慢了

把整个旅程连起来看

张三点提交

[网关] 鉴权/限流/路由

[订单服务]
   ├─(同步)问→ [用户服务] 是不是VIP        ┐
   ├─(同步)问→ [商品服务] 有没有货          │ 要立刻知道结果 = 同步
   ├─ 在订单库创建订单(待支付)              │
   ├─(异步)发→ 消息队列 →[商品服务]扣库存    ┐
   ├─(同步)叫→ [支付服务] 生成支付链接       │ 通知/善后 = 异步
   └─ 返回支付信息给张三 ← 用户到这就不用等了 │
        │                                 │
   (异步)发→ 消息队列 →[通知/积分/分析服务]  ┘

   全程带追踪号,被监控盯着

对照一下这一个流程里用到的所有概念:

环节用到的概念对应章节
请求统一入口、鉴权限流API 网关06
找到对方服务在哪服务注册与发现06
查 VIP、查库存、发起支付同步调用04
扣库存、发通知、加积分异步消息04
各服务查自己的库每服务一库05
扣库存失败则取消订单补偿 / 最终一致性05
排查哪一环慢链路追踪与监控06
这些服务怎么部署、扩容Docker + K8s07

小结

  • 一次”下单”,就把前面所有零件都用上了:网关进门 → 同步核对 → 创建订单+异步扣库存 → 同步发起支付 → 异步善后 → 全程被追踪监控
  • 关键区分:要立刻拿到结果的用同步,通知/善后的用异步
  • 跨服务数据不强求瞬时一致,靠消息 + 补偿达成最终一致。
  • 如果这一章的”电影”你能在脑子里顺下来,说明微服务的思维你已经建立起来了。

上一章 ← 07 - 微服务怎么跑起来:容器与编排 | 下一章 → 09 - 总结与避坑 | 回到 README 目录