下载工作台
企业级架构运维

跟练一:大促前架构评审(压测 + ADR)

试读上半部分 · 解锁后可读全文

第 16 章 · 跟练一:大促前架构评审(压测 + ADR)

类型:半日工作坊(约 3~4 小时)

角色:你任 首席架构师,向 ARB(架构评审委员会)汇报「贤紫社区电商 · 双 11 下单链路」扩容与保护方案。

前置:ch09 容量公式、ch13 SLO/ARB 流程、ch14 C4/ADR/容量表模板。

产出物(全部内嵌本章,无需外部 deliverables 目录):

  1. 容量估算工作表(§16.2)
  2. k6 压测脚本与结果分析(§16.3~16.4)
  3. ADR 三份完整模板(§16.6)
  4. ARB 答辩记录(§16.7)
  5. 大促 Runbook(§16.8)

16.0 工作坊环境准备

要求
集群小紫云计算 staging 集群,Namespace staging-app
服务order-api Deployment,可调副本数
工具k6、kubectl、Grafana 只读账号
权限可改 staging 副本数,不可直接改 prod
参考ch09 §9.3 压测方法、ch14 §14.9 容量表

检查命令

kubectl get deploy order-api -n staging-app
kubectl top pods -n staging-app -l app=order-api

16.1 业务背景(给定,勿改数字)

数值
日常 DAU80 万
大促 DAU200 万
大促窗口2 小时完成 45% 当日订单
人均订单0.4 单/天
秒杀毛刺系数峰值分钟内 ×3(相对稳态下单 QPS)
目标 SLA下单 P99 < 400ms,可用性 99.95%(ch13)
当前生产order-api 3 副本 2C4G
单 Pod 安全 QPS180(P99<300ms,错误<0.1%,ch09 基线)
成本因子每增 1 副本 2C4G ≈ 0.15 单位/月(ch09 §9.5)

系统边界:本跟练聚焦 POST /api/v1/orders;支付回调、搜索为 Tier-1,可引用但不展开。


16.2 任务一:填写容量估算工作表

复制下表到你的提交物,逐项手算并填写「你的结果」列
# 容量估算工作表 · 双 11 order-api 扩容

| 元数据 | 值 |
|--------|-----|
| 项目 | 贤紫社区电商双 11 |
| 作者 | (填写) |
| 日期 | |
| 关联 | ch09、ch13、ch14 §14.9 |

## A. 业务输入(给定)

| 项 | 值 |
|----|-----|
| 大促 DAU | 2,000,000 |
| 人均订单/天 | 0.4 |
| 2h 集中度 | 45% |
| SLO | 99.95%(21.6 min/月错误预算,ch13) |

## B. 流量计算(需手算)

| 步骤 | 公式 | 参考答案 | 你的结果 |
|------|------|----------|----------|
| 大促总订单量/天 | DAU × 人均 | 800,000 单 | |
| 2h 内订单量 | × 45% | 360,000 单 | |
| 2h 秒数 | 7200 | 7200 | |
| **稳态下单峰值 QPS** | 订单量/秒数 | **50 QPS** | |
| 秒杀毛刺 QPS | ×3 | **150 QPS** | |
| 下单占 API 总流量比 | 25% | — | |
| 网关等效 QPS | 50/0.25 | **200 QPS** | |

## C. 副本数(ch09 公式)

| 步骤 | 公式 | 参考答案 | 你的结果 |
|------|------|----------|----------|
| 理论副本(毛刺) | ceil(150/180×1.35) | **2** | |
| N+1 / 混合负载 | order-api 还承担查询等 | 需 >2 | |
| **ARB 决议副本** | 评审决定 | **6**(HPA max 10) | |

**为何不是 2 副本?** 答辩要点:

- 单服务混合 QPS(下单+查询+库存)实测可达 **120+**
- 大促需 **N+1**:任 1 Pod 故障仍扛毛刺
- 缩容窗口:大促后回到 3(见 Runbook §16.8)
- 成本增量:+3×0.15 = **+0.45 单位/月**(可接受 vs GMV)

## D. 中间件与 SLO

| 组件 | 毛刺 150 QPS 下评估 | 动作 |
|------|---------------------|------|
| MySQL 写 | ~150 TPS | 单库够;加慢查询告警 |
| Redis | 热点 SKU | 预热 + ch17 击穿防护 |
| DB 连接 | 6×20=120 | <350 ✅ |
| 错误预算 | 大促失败不得超 21.6min/月 | 限流+降级 ADR |

## E. 签字

| 架构 | SRE | DBA |
|------|-----|-----|
| | | |

16.3 任务二:staging k6 压测(分步实验)

Step 1:确认 staging 基线(3 副本)

kubectl scale deploy/order-api -n staging-app --replicas=3
kubectl rollout status deploy/order-api -n staging-app

Step 2:保存压测脚本 k6-order-create.js

import http from 'k6/http';
import { check, sleep } from 'k6';
import { Counter, Trend } from 'k6/metrics';

const errors = new Counter('order_errors');
const duration = new Trend('order_duration');

export const options = {
  scenarios: {
    ramp: {
      executor: 'ramping-vus',
      startVUs: 0,
      stages: [
        { duration: '2m', target: 30 },
        { duration: '5m', target: 80 },
        { duration: '3m', target: 100 },
        { duration: '2m', target: 0 },
      ],
      gracefulRampDown: '30s',
    },
  },
  thresholds: {
    http_req_failed: ['rate<0.01'],
    http_req_duration: ['p(99)<400'],
    order_errors: ['count<50'],
  },
};

const BASE = __ENV.API_BASE || 'http://staging-api.shop.local';

export default function () {
  const payload = JSON.stringify({
    userId: 10000 + (__VU % 5000),
    items: [{ skuId: 'SKU001', qty: 1 }],
  });
  const params = {
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${__ENV.TOKEN || 'staging-test-token'}`,
      'X-Idempotency-Key': `${__VU}-${__ITER}-${Date.now()}`,
    },
    tags: { name: 'createOrder' },
  };
  const res = http.post(`${BASE}/api/v1/orders`, payload, params);
  duration.add(res.timings.duration);
  const ok = check(res, {
    'status is 201': (r) => r.status === 201,
    'has orderId': (r) => r.json('orderId') !== undefined,
  });
  if (!ok) errors.add(1);
  sleep(0.1);
}

Step 3:执行压测

k6 run --out json=k6-result.json k6-order-create.js
# 或输出 HTML(需 k6 扩展)
# K6_WEB_DASHBOARD=true k6 run k6-order-create.js

Step 4:扩容到 6 副本复测

kubectl scale deploy/order-api -n staging-app --replicas=6
kubectl rollout status deploy/order-api -n staging-app
k6 run k6-order-create.js

Step 5:记录结果表(填入你的实测)

教学样本(3 副本)

阶段VU下单 QPSP50P99错误率
爬坡 2m309585ms210ms0%
稳态 5m80168120ms380ms0.3%
峰值 3m100195145ms520ms1.2%

教学样本(6 副本)

阶段VU下单 QPSP50P99错误率
稳态 5m8017295ms310ms0.1%
峰值 3m100198110ms350ms0.2%

结论写法(提交 ARB)

3 副本在 QPS>170 时 P99 突破 400ms SLO;6 副本在同等负载下 P99<400ms、错误率<0.1%,支撑 ADR-016-01

截图清单:Grafana order-api RED 面板、HPA 副本数、k6 终端 summary。


16.4 任务三:APISIX 限流配置(staging 验证)

# apisix-route-order-limit.yaml(片段)
routes:
  - uri: /api/v1/orders
    methods: [POST]

以下内容需解锁后阅读

试读已结束。解锁本章 ¥5.00,或开通年度会员畅读全部教程。
年度会员 ¥199.00/年; 小紫 AI 工作台有效会员 ¥99.00/年

正文仅在服务端鉴权后下发,未付费无法获取下半部分内容。