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 + K8s | 07 |
小结
- 一次”下单”,就把前面所有零件都用上了:网关进门 → 同步核对 → 创建订单+异步扣库存 → 同步发起支付 → 异步善后 → 全程被追踪监控。
- 关键区分:要立刻拿到结果的用同步,通知/善后的用异步。
- 跨服务数据不强求瞬时一致,靠消息 + 补偿达成最终一致。
- 如果这一章的”电影”你能在脑子里顺下来,说明微服务的思维你已经建立起来了。
上一章 ← 07 - 微服务怎么跑起来:容器与编排 | 下一章 → 09 - 总结与避坑 | 回到 README 目录