Little 定律与容量估算:如何从到达率和驻留时间推导资源
L=λW 是守恒关系,不是脱离稳态的扩容公式。
Java HotSpot GC 调优指南 强调吞吐、延迟与资源目标必须结合应用负载测量。
故障现场:局部数字为什么会给出错误结论
团队用 20 ms 服务时间乘峰值 800 RPS 得出 16 线程,却忽略连接等待、下游排队、突发持续时间和目标利用率,16 个 worker 很快全忙。 第一条规则是同时保存负载输入、业务输出和资源水位;只有结果数字而没有发生条件,无法区分代码变化、环境噪声、缓存热度和依赖波动。
先固定权威测量对象
Little 定律中的 W 是系统内驻留时间,L 是同一边界内平均在途量;边界不一致、系统持续积压或到达率不等于完成率时不能直接套公式。 正向实验达到预期吞吐和延迟,反向实验制造饱和、队列、暂停或依赖退化,并证明指标能揭示而非掩盖差异。
六段性能主链
Arrival rate λ
在 Arrival rate λ 阶段记录时间戳、计数、资源 owner、上限和失败原因。测量探针的开销单独评估;并行阶段按关键路径组合,串行阶段才允许求和。改变参数后重新验证上下游水位,避免把等待从一个队列搬到另一个队列。
Residence W
在 Residence W 阶段记录时间戳、计数、资源 owner、上限和失败原因。测量探针的开销单独评估;并行阶段按关键路径组合,串行阶段才允许求和。改变参数后重新验证上下游水位,避免把等待从一个队列搬到另一个队列。
In-flight L
在 In-flight L 阶段记录时间戳、计数、资源 owner、上限和失败原因。测量探针的开销单独评估;并行阶段按关键路径组合,串行阶段才允许求和。改变参数后重新验证上下游水位,避免把等待从一个队列搬到另一个队列。
Utilization
在 Utilization 阶段记录时间戳、计数、资源 owner、上限和失败原因。测量探针的开销单独评估;并行阶段按关键路径组合,串行阶段才允许求和。改变参数后重新验证上下游水位,避免把等待从一个队列搬到另一个队列。
Burst buffer
在 Burst buffer 阶段记录时间戳、计数、资源 owner、上限和失败原因。测量探针的开销单独评估;并行阶段按关键路径组合,串行阶段才允许求和。改变参数后重新验证上下游水位,避免把等待从一个队列搬到另一个队列。
Headroom
在 Headroom 阶段记录时间戳、计数、资源 owner、上限和失败原因。测量探针的开销单独评估;并行阶段按关键路径组合,串行阶段才允许求和。改变参数后重新验证上下游水位,避免把等待从一个队列搬到另一个队列。
性能结论先声明系统边界与负载模型
吞吐是单位时间完成的有效工作,不是接收数;并发是在途工作数,不是线程数;利用率是资源忙碌比例,不直接等价于业务容量。错误、超时和被保护策略拒绝的请求必须单列,不能从分母消失。若候选版本更快是因为少写一张表、跳过校验或异步后提前返回,它改变了语义而不是优化。
分布、排队和守恒关系必须同时成立
Little 定律在稳定边界内给出平均在途量 L=λW。它能做交叉校验:若 200 RPS、平均驻留 150 ms,则系统平均约 30 个在途请求;监控只有 8 个时,要检查边界、采样或吞吐口径。它不告诉你等待分布,也不保证高利用率下尾延迟;接近资源饱和时,微小流量或服务时间增长会令队列非线性上升。
负载发生器也会制造测量错误
闭环模型在收到响应后才发下一请求,服务暂停时客户端也停止施压,遗漏了本应在暂停期间到达的请求,这就是协调遗漏。开环模型按计划到达率发请求,更接近外部流量,但必须限制发生器自身 CPU、连接和队列,记录计划与实际发送偏差。若业务确实是“用户完成上一步才发下一步”,闭环有意义;两种模型不能混写。
资源池必须沿同一截止时间协作
线程池、连接池和下游并发限制串联时,最大池不会叠加成容量,而由最窄资源和服务需求决定。多层无界队列会让请求在入口等一遍、线程池等一遍、连接池再等一遍,超时后工作仍继续占资源。入口携带绝对 deadline,每一层从剩余预算派生等待/执行超时,取消后释放槽位并阻止迟到副作用。
虚拟线程降低线程持有成本,不增加数据库连接、CPU 或远端 QPS;连接池扩大会增加数据库活跃会话和锁竞争;批量与压缩减少网络调用却增加内存、延迟和 codec CPU。任何参数变化都观察瓶颈是否迁移,不能只看被优化局部的耗时。
JVM、GC 与操作系统证据不能脱离业务负载
CPU 利用率低不代表有余量,线程可能等锁、连接、磁盘或网络;CPU 高也可能是序列化、压缩、GC、TLS 或自旋而非业务计算。结合运行队列、上下文切换、缺页、磁盘时延、网络重传和容器 throttling,先定位资源需求再调整参数。
性能数据同样需要安全与治理
用阶梯负载画出拐点而不是只压一个峰值
从低负载开始按固定台阶提升到达率,每个台阶保持到吞吐、队列、CPU、连接、分配率和错误率稳定;记录计划到达、实际发送、完成和拒绝四条曲线。容量点不是 CPU 第一次到百分百,而是完成吞吐不再随到达率线性增长,或尾延迟、错误、积压、资源预算首次越过门禁。再降低负载观察曲线是否沿原路恢复;若队列、缓存驱逐、GC 或重试造成迟滞,安全运行点必须低于上升阶段的理论拐点。
突发实验在平均流量不变的情况下改变 burst 大小和持续时间,验证令牌、队列和自动扩缩容是否来得及吸收。故障容量则在一个实例、一个下游分片或部分连接不可用时重复阶梯,计算 N-1 容量而不是把健康集群峰值直接当发布额度。容量计划以故障态安全点、业务增长和测量误差共同留余量。
分层剖析必须回答时间和资源去了哪里
基准结果需要反事实与可回滚证据
两个 Java 17 模型固定量化见证
离线模型不冒充真实压测,只固定公式、边界和判定输出;真实环境再用直方图、JFR/GC 日志、数据库与消息指标证明同一不变量。
javac --release 17 -Xlint:all -Werror examples/backend-development/performance/little-law-capacity/LittleLawDemo.java examples/backend-development/performance/little-law-capacity/CapacityHeadroomDemo.java
java -cp examples/backend-development/performance/little-law-capacity LittleLawDemo
java -cp examples/backend-development/performance/little-law-capacity CapacityHeadroomDemoarrivalPerSec=200 meanSeconds=0.15 predictedInFlight=30 measuredInFlight=30 steady=true
peakRps=800 serviceMs=20 theoreticalConcurrency=16 safeUtilization=0.70 provisioned=24 headroom=8容量、回归与恢复门禁
容量表列出正常/峰值/故障流量、平均与尾驻留时间、目标利用率、队列上限、超时、实例数和单实例资源,结果用压测校正。 围绕“容量估算同时满足流量、驻留时间和在途量守恒,并明确稳态、突发与瓶颈假设”保存基线、候选、差值、原始分布和权威结果。过载实验还要证明拒绝有界、关键流量受保护、积压排空且恢复迟滞不会制造二次冲击;不满足任一项即阻止发布或自动回滚。
