4. 案例背景介绍:模拟电商系统架构与变更内容
本章节构建一个贴近真实生产环境的模拟电商系统,作为后续事故响应与故障定位的演练靶场。系统涵盖电商核心链路:前端展示 → 订单处理 → 支付网关 → 库存扣减 → 物流调度。所有服务均接入 Jaeger 分布式追踪,并模拟一次典型的“配置变更”引发级联故障。
4.1 系统整体架构
系统采用微服务架构,共包含 5 个核心服务与 3 个基础中间件。服务间通过同步 HTTP/gRPC 与异步消息队列混合通信。
架构设计要点:
- 每个服务独立部署,拥有独立的数据库实例(模拟 MySQL/Redis)。
- 服务间调用均携带 Jaeger Trace Context,形成完整调用链。
- 支付与库存服务之间存在分布式事务(TCC 模式),是故障高发区。
4.2 服务职责与调用关系
下表详细列出各服务的核心职责、技术栈以及在本案例中的关键依赖关系。
| 服务名称 | 核心职责 | 技术栈 | 关键依赖 |
|---|---|---|---|
| 前端 (Frontend) | 用户交互、商品展示、下单入口 | React + Nginx | 订单服务 |
| 订单 (Order) | 订单创建、状态管理、调用编排 | Spring Boot + MySQL | 支付、库存、物流 |
| 支付 (Payment) | 支付渠道对接、交易记录、回调通知 | Go + Redis | 订单服务(回调) |
| 库存 (Inventory) | 库存预占、扣减、释放(TCC 模式) | Java + MySQL + Redis | 订单服务(回调) |
| 物流 (Logistics) | 运单生成、配送调度、轨迹跟踪 | Python + Kafka | 订单服务、消息队列 |
关键调用链路(正常流程):
前端 → 订单(创建订单)→ 支付(发起支付)→ 订单(等待支付回调)→ 库存(扣减库存)→ 订单(更新状态)→ 物流(发送运单消息)→ 消息队列 → 物流服务(异步处理)。
前端 → 订单(创建订单)→ 支付(发起支付)→ 订单(等待支付回调)→ 库存(扣减库存)→ 订单(更新状态)→ 物流(发送运单消息)→ 消息队列 → 物流服务(异步处理)。
4.3 变更内容描述
本次事故的触发点是一次“库存服务连接池配置变更”。变更由 SRE 团队执行,旨在优化数据库连接利用率。以下是变更的详细描述。
4.3.1 变更背景
监控显示库存服务在高峰期出现数据库连接数接近上限的告警。DBA 建议将连接池最大连接数从 50 调整为 30,同时将连接超时时间从 30s 调整为 5s,以快速释放空闲连接。
4.3.2 变更操作步骤
- 修改库存服务配置文件
application-prod.yml中的数据库连接池参数。 - 通过 CI/CD 管道滚动重启库存服务实例(共 3 个 Pod)。
- 变更后未立即执行全链路压测,仅验证了单接口可用性。
4.3.3 变更参数对比
| 参数项 | 变更前 | 变更后 | 预期效果 |
|---|---|---|---|
maximum-pool-size |
50 | 30 | 降低数据库连接压力 |
connection-timeout |
30000 ms | 5000 ms | 快速失败,避免线程堆积 |
idle-timeout |
600000 ms | 300000 ms | 加速空闲连接回收 |
4.3.4 变更引入的隐患
变更后的参数在低并发场景下表现正常,但存在以下隐患:
- 连接池饥饿:最大连接数从 50 降至 30,在突发流量下容易导致连接池无可用连接。
- 超时过短:5s 的连接超时在数据库响应变慢(如慢查询、锁等待)时,会触发大量快速失败重试,形成“重试风暴”。
- 缺乏熔断:库存服务未配置 Hystrix/Resilience4j 熔断,失败重试会直接穿透到数据库层。
⚠️ 事故触发条件:变更上线 2 小时后,电商平台开启“限时秒杀”活动,瞬时流量达到平时的 5 倍。库存服务连接池迅速耗尽,大量请求超时,订单服务因等待库存回调而阻塞,最终导致整个下单链路雪崩。
4.4 变更窗口与事故时间线
为了在 Jaeger 中精准定位故障根因,必须明确变更窗口与事故爆发的时间对应关系。下表记录了关键时间节点。
| 时间 (T) | 事件 | 说明 |
|---|---|---|
| T-2h | 连接池配置变更上线 | 库存服务滚动重启完成,监控无异常 |
| T-5min | 秒杀活动开始 | 流量从 100 QPS 飙升至 500 QPS |
| T+0 | 事故爆发 | 库存服务连接池耗尽,订单服务开始超时 |
| T+2min | 订单服务雪崩 | 订单服务线程池阻塞,前端下单接口大面积 502 |
| T+5min | 告警触发 | Jaeger 监控到错误率 > 20%,SRE 介入 |
| T+15min | 回滚变更 | 库存服务连接池恢复至 50,系统逐步恢复 |
Jaeger 追踪的关键价值:在 T+2min 时,Jaeger 的 Trace 数据已经清晰显示出所有失败请求的根节点均为
InventoryService.deductStock(),且错误类型为 SQLException: Connection is not available, request timed out after 5000ms。这为快速定位变更根因提供了直接证据。