大促前两周,运维问架构师:“这次需要加多少台机器?”架构师打开去年大促的监控数据看了看,说:“去年 100 台顶住了,今年流量预计翻倍,加到 200 台吧。”运维追问:“内存要多大?磁盘要 SSD 还是 HDD?数据库连接池开多少?”架构师沉默了三秒,说:“先按去年配置来,不够了再加。”
大促当天,应用服务器 CPU 使用率只有 40%,但数据库连接池打满了——200 台应用服务器同时向数据库发起连接,远超数据库的最大连接数。紧急扩容数据库连接数后,数据库 CPU 飙到 95%,因为连接数增加导致并发查询暴增。最终靠临时关闭非核心功能才撑过峰值。
这个场景的根源不是”机器不够”,而是没有容量模型。容量规划(Capacity Planning)不是”估一下要多少台机器”,而是一个从需求预测到资源建模到验证反馈的完整工程过程。
本文要回答三个问题:
- 排队论(Queueing Theory)在容量规划中怎么用?Little 定律和 M/M/c 模型能给出什么?
- 容量基线(Baseline)和水位线(Waterline)怎么建、怎么管?
- 全链路压测怎么设计,才能真正验证容量模型而不只是”跑个数”?
在上一篇中,我们讨论了 SLO 工程——如何量化管理系统的可靠性。容量规划是 SLO 的前置条件:如果容量不足,再好的 SLO 也无法达标。
一、为什么”加机器”不是容量规划
“流量涨了就加机器”——这个策略在简单场景下有效,但随着系统复杂度增加,它的局限性会迅速暴露。
瓶颈不在你以为的地方
一个典型的请求链路涉及多个组件:负载均衡 → API 网关 → 应用服务 → 缓存 → 数据库 → 消息队列。每个组件都有自己的容量上限,系统整体容量取决于最窄的那个瓶颈。
你给应用服务加了 10 台机器,但瓶颈在数据库连接池(最多 500 个连接),那 10 台新机器只会让更多请求排队等待数据库连接,延迟反而增加。
资源之间的耦合
CPU、内存、磁盘 I/O、网络带宽之间不是独立的。增加并发线程数可以提高 CPU 利用率,但也会增加内存占用和上下文切换开销。当内存不足时,操作系统开始使用 Swap,磁盘 I/O 急剧增加,CPU 花在 I/O 等待上的时间增多,吞吐量反而下降。
非线性扩展
大多数系统的性能不会随资源线性增长。根据 Amdahl 定律(阿姆达尔定律):
加速比 = 1 / ((1 - P) + P / N)
P = 可并行化的比例
N = 处理器数量
如果一个系统 80% 的工作可以并行化(P = 0.8),那么即使你加无限台机器,理论最大加速比也只有 1 / (1 - 0.8) = 5 倍。剩余 20% 的串行部分(数据库写锁、分布式锁、全局序号生成)决定了系统的扩展上限。
USL 模型
Amdahl 定律假设并行部分没有协调开销,但实际系统中并行工作者之间需要通信和同步。Neil Gunther 提出的通用可扩展性定律(Universal Scalability Law,USL)在 Amdahl 定律基础上增加了”串扰”(Crosstalk)参数:
C(N) = N / (1 + α(N-1) + β·N·(N-1))
N = 节点数
α = 串行化参数(Amdahl 定律中的非并行部分)
β = 串扰参数(节点间通信开销)
C(N) = 相对吞吐量
当 β > 0 时,增加节点数到一定程度后,吞吐量不仅不增长,还会下降——因为节点间协调的开销超过了新增节点带来的收益。这就是为什么某些系统在扩容后性能反而变差。
二、排队论基础:Little 定律与 M/M/c 模型
排队论(Queueing Theory)是容量规划的数学基础。它不能精确预测系统在真实负载下的表现,但能提供一个方向性正确的分析框架。
Little 定律
Little 定律是排队论中最基本、最实用的结论:
L = λ × W
L = 系统中的平均请求数(正在处理 + 排队等待的)
λ = 到达速率(每秒到达的请求数,即 QPS)
W = 平均逗留时间(从请求到达到处理完成的总时间)
这个公式看似简单,但适用范围极广——它不依赖任何关于到达分布或服务时间分布的假设。
应用场景一:估算并发连接数。
假设一个 Web 服务的 QPS = 1000,平均响应时间 = 200 毫秒。
L = 1000 × 0.2 = 200
系统中平均有 200 个并发请求。这意味着至少需要 200 个工作线程(或连接)来处理这些请求。如果线程池大小设为 100,那一半的请求必须排队等待,延迟会显著增加。
应用场景二:评估扩容效果。
如果通过优化数据库查询,把平均响应时间从 200 毫秒降到 100 毫秒,相同的 QPS 下并发请求数降为:
L = 1000 × 0.1 = 100
不需要加机器,只需要优化代码,就把资源需求减半了。
M/M/c 模型
M/M/c 模型是排队论中用于分析多服务台(Multi-Server)系统的经典模型。
M = 到达过程服从泊松分布(Poisson Distribution)
M = 服务时间服从指数分布(Exponential Distribution)
c = 服务台数量(即可并行处理请求的工作者数量)
核心参数:
ρ = λ / (c × μ) = 系统利用率
λ = 到达速率
μ = 单个服务台的服务速率(1 / 平均服务时间)
c = 服务台数量
当 ρ 接近 1 时,队列长度趋向无穷大,延迟急剧增加。这是容量规划中最重要的结论:不要让系统利用率接近 100%。
平均响应时间
↑
| /
| /
| /
| /
| /
| /
| /
| /
| /
| ──
| ──
+——————————————————————→ 利用率 ρ
0% 50% 80% 90% 100%
M/M/c 模型给出了一个关键的工程建议:CPU 利用率的安全水位线应该控制在 60-75%。超过这个范围后,排队延迟会快速增长。
| CPU 利用率 | 排队延迟增幅(相对于空闲时) | 工程建议 |
|---|---|---|
| 30% | 约 1.4x | 安全,有充足余量 |
| 50% | 约 2x | 正常运行水位 |
| 70% | 约 3.3x | 接近水位线,准备扩容 |
| 80% | 约 5x | 超出水位线,应立即扩容 |
| 90% | 约 10x | 危险,延迟显著恶化 |
| 95% | 约 20x | 紧急,系统即将不可用 |
排队论的局限
排队论模型基于一系列理想假设(泊松到达、指数服务时间、无限队列长度),真实系统的行为往往偏离这些假设:
- 到达过程不是泊松分布。真实流量有突发性(Burstiness),尤其是大促开始瞬间的流量尖峰,比泊松分布预测的极端情况更极端。
- 服务时间不是指数分布。数据库查询的响应时间通常是双峰分布——缓存命中时很快,缓存未命中时很慢。
- 队列不是无限的。线程池有大小限制,连接池有上限,超出限制的请求会被拒绝而不是排队。
因此,排队论应该用来做”方向性判断”(这个配置大概能不能扛住这个负载),不能用来做”精确预测”。精确预测需要全链路压测。
三、资源建模:CPU、内存、I/O、网络
容量规划需要对每种资源分别建模,然后找出最先触达瓶颈的资源——它决定了系统的整体容量上限。
CPU 建模
CPU 需求 = 每个请求的 CPU 时间 × 请求速率
CPU 容量 = CPU 核心数 × (1 - 安全余量)
最大 QPS = CPU 容量 / 每个请求的 CPU 时间
例如:一台 8 核服务器,每个请求平均消耗 4 毫秒的 CPU 时间,安全余量 30%。
CPU 容量 = 8 × (1 - 0.3) = 5.6 核
最大 QPS = 5600 毫秒/秒 / 4 毫秒/请求 = 1400 请求/秒
注意:这里的”CPU 时间”是纯 CPU 计算时间,不包括 I/O 等待。如果一个请求的总响应时间是 100 毫秒但 CPU 时间只有 4 毫秒,说明 96 毫秒花在了 I/O 等待上——这种情况下 CPU 通常不是瓶颈。
内存建模
内存需求 = 基础内存 + 每连接内存 × 并发连接数 + 缓存大小
基础内存 = JVM 堆 + 操作系统 + 其他常驻进程
每连接内存 = 请求缓冲区 + 线程栈 + 上下文数据
Java 应用的典型内存构成:
- JVM 堆(Heap):4-8 GB。
- JVM 非堆(Metaspace、Code Cache 等):256-512 MB。
- 每个线程栈:512 KB-1 MB。200 个线程 = 100-200 MB。
- 操作系统和其他开销:500 MB-1 GB。
- 总计:单个实例需要 6-10 GB 内存。
磁盘 I/O 建模
IOPS 需求 = 每个请求的 I/O 操作数 × 请求速率
IOPS 容量 = 磁盘的 IOPS 上限
HDD:约 100-200 IOPS(随机读写)
SSD:约 10000-100000 IOPS
NVMe SSD:约 100000-1000000 IOPS
如果每个数据库查询平均产生 5 次随机磁盘读取,QPS = 1000 时需要 5000 IOPS。HDD 无法满足,必须使用 SSD。
网络建模
带宽需求 = 每个请求的数据量 × 请求速率
入方向:请求体大小 × QPS
出方向:响应体大小 × QPS
如果平均响应体大小 = 10 KB,QPS = 10000:
出方向带宽 = 10 KB × 10000 = 100 MB/s = 800 Mbps
一根千兆网卡(1 Gbps)在 80% 利用率时只能提供 800 Mbps,刚好触达上限。这种情况下需要万兆网卡或多网卡绑定。
综合建模
把各维度的容量上限汇总,找出最低的那个——它就是系统的瓶颈。
graph TD
subgraph 资源容量模型
CPU["CPU<br/>单机最大 QPS: 1400"]
MEM["内存<br/>单机最大连接: 200"]
DISK["磁盘 I/O<br/>单机最大 QPS: 2000<br/>(SSD)"]
NET["网络<br/>单机最大 QPS: 12500<br/>(万兆网卡)"]
end
CPU --> BN["瓶颈分析"]
MEM --> BN
DISK --> BN
NET --> BN
BN --> RESULT["系统瓶颈: CPU<br/>单机最大 QPS = 1400<br/>目标 QPS = 10000<br/>需要 8 台应用服务器"]
四、需求预测:从历史数据到业务增长
容量规划的输入是”未来需要多少容量”。这个预测来自两个方向:历史趋势外推和业务增长预期。
历史趋势外推
收集过去 3-12 个月的流量数据(QPS、DAU、订单量等),拟合增长曲线,外推到目标时间点。
常见的增长模型:
- 线性增长:y = a + bx。适用于成熟期的稳定业务。
- 指数增长:y = a × e^(bx)。适用于增长期的业务。
- 对数增长:y = a + b × ln(x)。适用于接近饱和的业务。
QPS
↑
| ○ ○ ○ ← 线性外推
| ○
| ○
| ○
| ○
| ○
| ○
+——————————————→ 时间
历史数据 预测
注意:历史趋势外推假设未来的增长模式与过去相同。如果业务计划有大的变化(例如新增一个大客户、开拓新市场),历史趋势就不准了。
业务增长预期
与产品和业务团队对齐未来的业务计划:
- 预计新增多少用户?
- 是否有大型营销活动或促销?
- 是否计划开拓新地域/新市场?
- 是否有新功能会改变用户行为(例如一个新的视频功能会显著增加带宽需求)?
把业务预期转化为技术指标:
预计新增 100 万 DAU(日活跃用户)
→ 平均每用户每日请求 50 次
→ 日增请求量 5000 万
→ 峰值系数 3x(峰值 QPS ≈ 平均 QPS × 3)
→ 峰值 QPS 增量 = 5000 万 / 86400 × 3 ≈ 1736 QPS
峰值估算
容量规划必须基于峰值而非平均值。峰值 / 平均值的比率(Peak-to-Average Ratio)因业务类型而异:
| 业务类型 | 峰均比 | 说明 |
|---|---|---|
| 企业 SaaS | 2-3x | 工作日白天是峰值,夜间和周末是低谷 |
| 社交媒体 | 3-5x | 午间和晚间峰值明显 |
| 电商(日常) | 3-5x | 晚间购物高峰 |
| 电商(大促) | 10-50x | 大促开始瞬间流量尖峰 |
| 游戏 | 5-10x | 新版本上线、节假日 |
大促场景下的峰值估算尤其困难。2019 年天猫双十一零点峰值达到 54.4 万笔/秒,是日常峰值的数十倍。这种量级的尖峰,历史趋势外推几乎无法预测,必须结合业务部门的营销计划和流量预估。
五、容量基线与水位线管理
容量基线
容量基线(Capacity Baseline)是系统在标准负载下各项资源指标的正常范围。它是容量管理的”参照物”。
建立基线的步骤:
- 选择一个代表性的时间段(通常是最近 4-8 周的工作日)。
- 排除异常数据点(故障期间、大促期间)。
- 计算各指标的统计分布:p50、p90、p99、最大值。
- 将基线文档化,并与团队共享。
基线指标示例:
┌────────────────────────────────────────────────┐
│ 容量基线 — 订单服务 — 2025 Q4 │
├────────────────┬──────┬──────┬──────┬──────────┤
│ 指标 │ p50 │ p90 │ p99 │ 峰值 │
├────────────────┼──────┼──────┼──────┼──────────┤
│ QPS │ 800 │ 1200 │ 1500 │ 2000 │
│ CPU 利用率(%) │ 35 │ 50 │ 65 │ 78 │
│ 内存利用率(%) │ 60 │ 65 │ 70 │ 75 │
│ DB 连接池利用率 │ 30 │ 45 │ 60 │ 72 │
│ p99 延迟(ms) │ 120 │ 180 │ 350 │ 800 │
└────────────────┴──────┴──────┴──────┴──────────┘
水位线
水位线(Waterline)是各资源指标的告警阈值,分为多个级别:
| 级别 | CPU 利用率 | 内存利用率 | DB 连接池 | 动作 |
|---|---|---|---|---|
| 绿色 | < 50% | < 60% | < 50% | 正常运行 |
| 黄色 | 50-70% | 60-75% | 50-70% | 关注,制定扩容计划 |
| 橙色 | 70-80% | 75-85% | 70-85% | 告警,启动扩容流程 |
| 红色 | > 80% | > 85% | > 85% | 紧急,立即扩容或降级 |
水位线的设定要考虑扩容的提前量(Lead Time)。如果从决定扩容到新资源上线需要 2 小时(包括审批、采购、部署、预热),那么在达到橙色水位线时就应该开始扩容,不能等到红色才动手。
水位线与 SLO 的关系
水位线是保障 SLO 的”提前预警”。如果 CPU 持续在红色水位线运行,排队延迟会急剧增加,最终导致延迟 SLO 被突破。
flowchart LR
A["资源水位监控"] --> B{"当前水位"}
B -->|绿色| C["正常运行"]
B -->|黄色| D["生成扩容报告<br/>排入下周计划"]
B -->|橙色| E["触发扩容工单<br/>2小时内完成"]
B -->|红色| F["紧急扩容<br/>+ 启动降级预案"]
E --> G["扩容完成<br/>水位回落"]
F --> G
G --> A
六、全链路压测
容量模型给出了理论预测,全链路压测(Full-Chain Load Testing)是验证这个预测的唯一手段。
什么是全链路压测
与传统的单接口压测不同,全链路压测模拟真实用户的完整行为链路——从浏览商品、加入购物车、提交订单到完成支付——按照真实的流量比例同时施压。
传统压测:只压一个接口
压测工具 ──→ 搜索 API ──→ 看搜索 API 扛多少 QPS
全链路压测:按真实比例压所有接口
压测工具 ──→ 搜索 API (50%)
──→ 详情 API (30%)
──→ 下单 API (15%)
──→ 支付 API (5%)
压测环境
全链路压测最理想的方式是在生产环境做。原因是:
- 测试环境的硬件配置、网络拓扑、数据量、中间件版本与生产环境不同,压测结果不可信。
- 测试环境的数据量通常远小于生产环境,数据库查询在小数据量下的表现与大数据量下完全不同。
在生产环境做压测需要解决两个关键问题:
流量隔离:压测流量必须与正常用户流量隔离,不能影响真实用户。常见方案是在请求头中添加压测标识(如
X-Test: shadow),中间件根据标识把压测请求路由到影子表/影子库。
数据隔离:压测产生的数据(订单、支付记录等)不能混入正常业务数据。解决方案包括影子数据库(Shadow Database)、影子表(Shadow Table)或压测结束后清理数据。
压测流量模型设计
压测流量模型需要尽可能贴近真实流量的特征:
- 请求比例:各接口的请求比例应与真实流量一致。
- 用户行为序列:用户不是随机访问接口的,而是按照一定的路径(浏览 → 加购 → 下单 → 支付)。
- 数据分布:热门商品和冷门商品的访问比例、大额订单和小额订单的比例。
- 时间模式:流量的递增模式。大促流量不是匀速增长的,而是在开始瞬间有一个陡峭的尖峰。
压测指标收集
压测过程中需要监控的核心指标:
┌──────────────────────────────────────────────────┐
│ 全链路压测监控面板 │
├────────────────┬─────────────────────────────────┤
│ 业务指标 │ QPS、成功率、错误类型分布 │
│ 延迟指标 │ p50、p90、p99、max │
│ 应用指标 │ CPU、内存、GC 次数/时长、线程数 │
│ 数据库指标 │ 连接数、QPS、慢查询数、锁等待 │
│ 缓存指标 │ 命中率、内存使用、连接数 │
│ 消息队列指标 │ 积压量、消费速率、延迟 │
│ 网络指标 │ 带宽、连接数、TCP 重传率 │
└────────────────┴─────────────────────────────────┘
压测分析与调优
压测结果的分析不是”看 QPS 够不够”,而是找出系统在压力下的行为模式:
- 瓶颈在哪? 哪个组件最先达到容量上限?
- 劣化曲线是什么形状? 性能是线性下降还是突然崩塌?
- 恢复能力如何? 流量回落后,系统能否快速恢复到正常水平?
七、容量规划流程
把上述方法论整合为一个可执行的流程:
度量 → 建模 → 预测 → 供给 → 验证 → 反馈
1. 度量:收集当前系统的性能基线数据
2. 建模:构建资源消耗模型(CPU/内存/IO/网络)
3. 预测:结合业务增长预期,计算未来资源需求
4. 供给:采购/申请/预留资源
5. 验证:通过全链路压测验证预测的准确性
6. 反馈:用压测结果修正模型,迭代优化
时间线
| 时间节点 | 动作 | 产出 |
|---|---|---|
| T-90 天 | 收集历史数据,构建容量模型 | 容量模型文档 |
| T-60 天 | 与业务团队对齐增长预期,计算资源需求 | 资源需求清单 |
| T-45 天 | 提交资源申请,启动采购 | 采购订单 |
| T-30 天 | 资源到位,部署并加入集群 | 扩容完成报告 |
| T-14 天 | 第一轮全链路压测 | 压测报告、问题清单 |
| T-7 天 | 修复问题后第二轮压测 | 验证报告 |
| T-3 天 | 最终检查,确认所有预案就位 | 上线 Checklist |
| T-0 | 大促 / 上线 | 实时监控 |
| T+7 天 | 复盘,修正容量模型 | 复盘报告 |
八、工程案例:某电商平台的大促容量规划
以下案例基于国内某大型电商平台公开的技术分享,展示了一次双十一大促的容量规划全过程。
背景
- 日常峰值 QPS:约 5 万。
- 大促目标峰值 QPS:50 万(10 倍于日常)。
- 核心链路:搜索 → 详情 → 加购 → 下单 → 支付。
- SLO 要求:可用性 >= 99.95%,下单 API p99 延迟 <= 1 秒。
容量模型
第一步:度量当前基线。
在日常峰值 5 万 QPS 下:
- 应用服务器 40 台(每台最大承载 1800 QPS,当前负载约 1250 QPS)。
- MySQL 主从集群,主节点 CPU 利用率 45%,连接数约 2000。
- Redis 集群 6 节点,内存使用率 55%,QPS 约 15 万。
第二步:资源需求预测。
目标 QPS = 50 万,是日常的 10 倍。但不是所有组件都需要线性扩容 10 倍:
- 应用服务器:线性扩容。50 万 / 1800 = 278 台,加上 30% 安全余量 = 362 台。
- Redis:QPS 线性增长到 150 万。需要 6 × 10 = 60 节点。但内存不需要 10 倍——热点数据是有限的。预估需要 40 节点。
- MySQL:不能线性扩容。数据库的瓶颈是写入和锁竞争,不是纯粹的 QPS。解决方案是增加分库分表数量、引入读写分离、热点数据使用缓存挡住 80% 的读请求。
第三步:关键决策。
- 数据库分库数从 8 扩到 64,每个库的连接数和写入量降为 1/8。
- 引入本地缓存(Caffeine,本地缓存)+ Redis 二级缓存,将数据库读 QPS 降低 90%。
- 订单创建使用异步化:前端先返回”订单创建中”,后台通过消息队列异步写入数据库。
全链路压测
第一轮压测(T-14 天):
压到目标 QPS 的 80%(40 万)时,发现以下问题:
- Redis 集群某些节点出现热点 Key(某爆款商品的库存 Key),单节点 CPU 打到 95%。
- 下单 API 的 p99 延迟飙到 3.2 秒,超过 1 秒的 SLO。瓶颈定位到分布式锁的竞争。
- 消息队列消费端出现积压,原因是消费者数量不足。
修复措施:
- 热点 Key 问题:引入本地缓存 + Key 分片策略(同一个逻辑 Key 分散到多个物理 Key)。
- 分布式锁竞争:把库存扣减改为基于 Redis Lua 脚本的原子操作,消除分布式锁。
- 消息队列积压:增加消费者实例数,从 16 个扩到 64 个。
第二轮压测(T-7 天):
成功压到 55 万 QPS(110% 目标值),所有 SLO 达标:
- 可用性:99.97%。
- 下单 API p99 延迟:780 毫秒。
- MySQL 主节点 CPU 利用率:62%(安全水位内)。
- Redis 集群最大节点 CPU 利用率:71%(接近黄色水位线但可接受)。
大促当天
实际峰值 QPS = 48 万,略低于预估的 50 万。所有指标在安全水位内,无重大故障。
复盘
- 应用服务器实际使用了 362 台中的 320 台(利用率约 88%),多余的 42 台是冗余。但考虑到安全余量,这个冗余是合理的。
- 容量模型对 Redis 的预测偏保守(预估 40 节点,实际 32 节点就够了),下次可以减少。
- 数据库的分库分表方案有效,但运维复杂度显著增加。建议长期迁移到分布式数据库。
九、容量规划的权衡
| 维度 | 过度规划(Over-Provisioning) | 合理规划 | 不足规划(Under-Provisioning) |
|---|---|---|---|
| 资源成本 | 高(大量闲置) | 适中 | 低(但故障损失可能更高) |
| 可用性风险 | 低 | 低 | 高 |
| 资源利用率 | 低(20-30%) | 中(50-70%) | 高但不稳定 |
| 规划投入 | 低(直接多买) | 高(需要建模和压测) | 低(但事后救火投入更高) |
| 弹性应对 | 好(有余量吸收突发) | 好(有计划性的弹性策略) | 差(突发即过载) |
| 适用场景 | 关键金融系统、不允许任何风险 | 大多数生产系统 | 早期创业、POC 验证 |
容量规划与云计算
云计算的弹性伸缩(Auto Scaling)能力部分缓解了容量规划的压力——不需要提前几个月采购硬件,可以按需扩缩。但云计算没有消除容量规划的需要:
- 弹性伸缩有延迟。从触发扩容到新实例可用,通常需要 2-5 分钟。大促开始瞬间的流量尖峰来不及扩容。
- 预留实例更便宜。按需实例(On-Demand)的价格通常是预留实例(Reserved Instance)的 2-3 倍。如果能预测基础用量,用预留实例 + 按需实例的组合可以显著降低成本。
- 数据层不容易弹性伸缩。数据库、缓存、消息队列的扩缩容涉及数据迁移和状态同步,不是简单地”加一台机器”就行。
十、结论
容量规划的本质是一个预测 → 验证 → 修正的迭代过程:
- 不要靠猜。用排队论和资源模型做方向性预测,用全链路压测做精确验证。
- 找瓶颈,不是堆资源。系统性能取决于最窄的瓶颈,堆资源到非瓶颈组件是浪费。
- 管水位线,不是看平均值。峰值决定容量需求,p99 比 p50 重要。
- 留余量,但不要过度。70% 的利用率水位线是一个合理的起点。
- 持续迭代。每次大促或重大发布后,用真实数据修正容量模型。
容量规划不是一次性项目,是一个持续运转的工程流程。做得好,它是护城河——让你在竞争对手被流量击垮时稳如磐石。做得差,它是隐形炸弹——在你最需要系统稳定的时候爆炸。
导航
上一篇:SLO 工程:可靠性的量化管理
下一篇:混沌工程:主动验证系统的韧性
参考资料
书籍
- Neil J. Gunther, “Guerrilla Capacity Planning”, Springer, 2007. 容量规划领域的经典著作,详细推导了 USL 模型。
- Neil J. Gunther, “Analyzing Computer System Performance with Perl::PDQ”, Springer, 2011. 排队论在系统性能分析中的应用。
- John Allspaw, “The Art of Capacity Planning”, O’Reilly, 2008. 从 Flickr 的实践出发,讲解 Web 应用的容量规划方法论。
- Martin Kleppmann, “Designing Data-Intensive Applications”, O’Reilly, 2017. 数据层扩展和分区策略的权威参考。
论文
- John D.C. Little, “A Proof for the Queuing Formula: L = λW”, Operations Research, 1961. Little 定律的原始论文。
- Gene M. Amdahl, “Validity of the Single Processor Approach to Achieving Large Scale Computing Capabilities”, AFIPS Conference Proceedings, 1967. Amdahl 定律的原始表述。
工业实践
- 阿里巴巴技术博客, “全链路压测体系建设”, 2020. 双十一全链路压测的方法论和工程实践。
- 美团技术博客, “美团点评大规模微服务容量规划实践”, 2021. 基于排队论的容量模型在美团的应用。
- Google SRE Book, Chapter 18: “Software Engineering in SRE”. 容量规划与需求预测的自动化方法。
工具
- Locust: GitHub 仓库(locustio/locust),基于 Python 的分布式负载测试工具。
- k6: GitHub 仓库(grafana/k6),基于 Go 的现代化负载测试工具。
- Gatling: GitHub 仓库(gatling/gatling),基于 Scala 的高性能负载测试工具。
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【系统架构设计百科】性能建模:用数学思维分析系统瓶颈
深入讲解性能建模的核心数学工具——Little 定律、M/M/1 与 M/M/c 排队模型、USL 通用可扩展性定律以及 USE 方法,用公式推导、代码实现和真实案例帮助架构师在改代码之前就定位系统瓶颈。
【系统架构设计百科】全链路压测:大规模系统的性能验证
从流量录制与回放、影子流量架构到压测数据隔离,系统讲解如何在不影响生产环境的前提下验证系统的真实性能极限。
【系统架构设计百科】架构质量属性:不只是"高可用高性能"
需求评审时写下的'高可用、高性能、高并发',到了架构设计阶段几乎无法落地——因为它们不是可执行的需求。本文从 SEI/CMU 的质量属性理论出发,用 stimulus-response 场景模型把模糊需求变成可量化、可验证的架构约束,并拆解属性之间的冲突与联动关系。
【系统架构设计百科】告警策略:如何避免"狼来了"
大多数团队的告警系统都在制造噪声而不是传递信号。阈值告警看似直观,实则产生大量误报和漏报,值班工程师在凌晨三点被叫醒,却发现只是一次无害的毛刺。本文从告警疲劳的工业数据出发,拆解基于 SLO 的多窗口燃烧率告警算法,深入 Alertmanager 的路由、抑制与分组机制,结合 PagerDuty 的告警疲劳研究和真实工程案例,给出一套可落地的告警策略设计方法。