用 Little‘s Law 把 QPS、平均耗时和并发数算成一本明白账
看压测报告的时候很多人习惯先看 QPS再看平均耗时的红绿灯然后就开始讨论要不要加机器。我建议先做一道小学数学题把 QPS 和平均耗时相乘。这个乘积就是并发数而把三者拴在一起的绳子叫 Littles Law。它的价值在于你不用再去争论“系统到底能扛多少并发”这种玄学问题压测数据、监控曲线、限流阈值全都变成了一笔能对上的账。这篇文章适合后端开发、测试工程师和运维同学尤其是那些被性能优化、容量规划和接口变慢问题反复折腾的人。1. 从压测报告里的两个数算出第三个数公式的来龙去脉1.1 Littles Law 到底在说什么Littles Law 是排队论里极其经典的结果1961 年被严格证明形式只有一句话长期稳定的系统中系统里任务的平均数量等于任务平均到达速率乘以任务在系统中的平均停留时间。写成符号就是 L λ × W换成我们日常说的指标就是并发数 QPS × 平均耗时。这个结论厉害的地方在于它完全不依赖系统内部怎么实现。你是单线程串行处理还是二十个线程的线程池还是异步事件循环甚至是消息队列后面挂一堆 worker只要系统进入稳定状态也就是到达速率和完成速率长期相等等式就成立。你不需要理解排队论的推导过程只需要把它当成一把永远好用的尺子。我第一次真正理解它是在一次压测复盘会上。当时大家争论“200 并发连接算不算高并发”有人拿线程池说事有人拿数据库连接池说事谁也说服不了谁。后来我们把压测工具报告里的 QPS 和平均耗时乘了一下发现系统里任意瞬间平均只有几十个请求在途所谓“200 并发”看起来吓人实际上大部分连接都闲着。从那天起我就把这三个数当成一个整体来看再也不单独讨论其中任何一个。1.2 先用一顿饭把公式翻译成人话我习惯用餐厅举例。一家餐厅每分钟进来 10 拨客人这是到达速率 λ每拨客人从进门到离开平均待 30 分钟这是 W。那么任意时刻餐厅里平均会有 300 拨客人这就是 L。10 乘以 30 等于 300没有更高深的道理本质就是在途量的算术。换算到系统里一个 QPS 为 1000、平均耗时 50ms 的服务任意一瞬间平均有 50 个请求正在被处理或者排队。如果这个服务的线程池上限是 200说明平均有四分之三的线程空闲如果线程池上限只有 20说明平均有 30 个请求挤在队列里那 50ms 的耗时里相当一部分不是处理时间而是等待时间。同一个 QPS 和耗时背后的资源状况可以天差地别这就是为什么增量地看“并发数”比单纯看 QPS 更能反映系统的真实水位。这个例子还能帮你理解另一个现象为什么系统变慢时你加再多的机器都不一定有用。如果瓶颈在某个共享的资源上比如数据库连接池那么流量进来后所有请求都在那个池子前面排队每台新增实例只会让排队队伍更长而不是让它变短。公式里的 W 包含了排队时间所以并发数会跟着上涨但它并不告诉你排队发生在哪一层这个定位动作后面专门讲。1.3 计算别栽在单位上公式里 QPS 单位是次/秒耗时单位是秒相乘结果是一个无量纲的“请求数”也就是任意瞬间平均在途请求的个数。而实际项目里耗时几乎都是毫秒给出来的所以这里要先除以 1000否则一个 QPS 1000、耗时 50ms 的系统会被算成 50000 个并发直接虚惊一场。下面这段 Python 我常年放在笔记里拿到压测报告就顺手抄过来算一遍你也可以直接存下来当参考# 已知 QPS 和平均耗时算系统内在途并发数 qps 1000 # 每秒完成的请求数 rt_ms 50 # 平均耗时毫秒 concurrency qps * rt_ms / 1000 print(f理论在途并发: {concurrency:.1f})你可以顺手验证一下自己的压测报告把工具给出的 QPS 和平均耗时代进去得到的数字应该和你预期的并发量级一致。如果不一致恭喜后面几节就是为你准备的。提示这套乘法只在系统处于稳定状态时成立。服务刚启动、流量陡增或者发布变更的瞬间在途请求数会剧烈波动别拿那段时间的监控数据去硬套公式否则会得出完全错误的结论。2. 用公式交叉验证压测结果数据自洽才是好报告2.1 先把“并发”这个词分成三层压测报告里的“并发”至少有三个不同含义混在一起绝对会翻车。客户端并发是压测工具开出来的线程或连接数代表你注入了多少压力服务端在途并发是从服务端监控的 QPS 和耗时算出来的代表后端进程里同时存活的请求数下游在途并发则是数据库、缓存或下游 RPC 视角上的请求规模。三层数字本来就该不一样但不能差得离谱。口径QPS 来源耗时来源算出的并发含义客户端视角压测工具吞吐压测工具平均耗时整条链路同时在途的请求总量服务端视角接入层/应用监控应用内耗时埋点服务进程内的在途请求下游视角数据库/下游监控慢查询或链路耗时单个下游的排队与处理规模实际排查问题时我经常把这三个口径分别算一遍再和各自对应的资源上限比。服务端在途并发接近线程池上限说明应用层打满了下游在途并发接近连接池上限说明瓶颈在数据库或下游 RPC只有整条链路的数据自洽你才能确信压测结果反映的是系统真实容量而不是某个环节的假象。2.2 客户端并发远高于理论在途并发先怀疑测试姿势我见过一份很典型的报告压测工具开 200 个并发连接打出来的 QPS 是 2000平均耗时 90ms。代入公式服务端理论在途并发 2000 × 0.09 180。客户端并发 200服务端在途 180两边接近说明连接复用得好、网络开销小这份压测结果自洽可以放心往下分析。反过来另一种情况同样的 200 个并发连接报告显示 QPS 只有 1500平均耗时却是 300ms。按公式算服务端在途并发 1500 × 0.3 450比客户端并发的 200 还高一倍多。此时第一步不是去优化代码而是先检查测试姿势压测脚本里是不是一次请求里串行发了多个子请求工具统计的耗时是单次请求的端到端耗时还是某个下游调用的耗时连接是不是复用了这些都会让客户端并发和服务端在途并发两个口径错位。数据不自洽的压测报告后面的所有优化结论都站不住。2.3 一套我长期在用的检查步骤拿到一份压测报告我会按下面顺序过一遍数字先记录工具的注入并发、QPS 和平均耗时再算出理论在途并发并和注入并发比较偏差超过 30% 就停下来查测试脚本然后用服务端监控里的真实 QPS 和平均耗时再算一次和工具侧结果比较偏差大说明链路里有网络、代理或限流组件在干预最后单独把数据库等下游的 QPS 和耗时代进去算确认下游的在途规模没有超过它自己的连接池上限。这四步做完这份报告才算真正能用来做决策。这几步看起来繁琐其实每次就是几分钟的算术。但正是这几分钟的乘法帮我挡掉了不少次“性能优化一个月结果压测机自己先崩了”的尴尬。数据先自洽再谈优化这个顺序不能反。3. 耗时是这个公式里最深的坑口径、均值与排队时间3.1 公式里的 W 是平均耗时不是 P99很多人习惯盯着 P99 看因为它代表最差体验。但 Littles Law 里的 W 是数学期望也就是平均耗时用 P99 代入会成倍高估在途并发得出“系统马上就要爆”的错误判断。压测报告里一般都会给平均耗时这个数就是用来和 QPS 做乘法的而 P99 是留给 SLO 和告警阈值的两者分工不同。平均值本身也有长尾问题。1000 个请求999 个耗时 50ms1 个耗时 5 秒平均耗时是 (999 × 50 5000) ÷ 1000 54.95ms。一个极端请求就会把平均值抬高 10%。所以在容量规划时我习惯算两个数用平均值算“平时在途并发”用 P99 算“极端时刻的在途压力上限”前者是常态水位后者决定资源余量别混着用。3.2 响应时间包含排队时间这恰恰是它的用处响应时间从来不是单纯的处理时间而是排队时间加服务时间可能还要加一点调度和网络开销。Littles Law 里的 W 是整套时间包含排队。这反而是公式最好用的地方当 QPS 上升时如果 W 也上升而代码处理路径没变那多出来的部分几乎都是排队时间。换句话说系统变慢不一定因为单请求变重更常见的是入口流量超过了某个资源的处理能力请求开始在队列里累积。这个认知在故障排查时能直接指向根因。假设 QPS 翻倍、平均耗时从 120ms 涨到 300ms但 CPU 只有 40%线程利用率也不高。这时候把每一层的 QPS 和耗时分别代入公式算在途并发哪一层的在途数明显超过它的资源上限哪层就是排队源头。比如数据库连接池上限 100算出来数据库侧在途并发 160那就说明请求在等数据库连接线程被占住但 CPU 闲着典型的“等 IO”型瓶颈。3.3 算完之后的余量判断技巧算出的在途并发如果长期低于线程池上限说明线程在空转或者等待外部资源如果长期接近线程池上限说明系统已经进入排队区。进入排队区之后响应时间的上涨会比 QPS 的上涨更明显因为排队时间是近似非线性增长的——来一个请求多等一截队伍越排越长耗时被迅速放大。我习惯把计算出来的在途并发曲线和线程池活跃线程数曲线放在同一张图里看两条线贴得很近说明计算口径没问题系统状态健康两条线长期分离要么是耗时口径选错了要么是中间有隐性队列。这个对比比单独看任何一条线都直观强烈建议你试一次。4. 反着用才值钱容量规划与限流阈值的两种算法4.1 正向推算目标耗时和峰值 QPS 决定并发资源正向用公式的思路是给定你能接受的耗时目标和预测的峰值流量反推系统需要容纳多少在途请求。假设业务要求 P95 耗时不超过 200ms峰值 QPS 预计 3000处理本身平均耗时按目标的六成估算成 120ms那么并发容量 3000 × 0.12 360。这意味着从线程池到数据库连接池再到下游系统的并发上限至少要为 360 个在途请求留位置。如果当前线程池最大只有 200那 160 个请求必然在排队最终耗时不可能落在 200ms 以内。这种推演能在上线前就发现问题而不是等压测打挂之后再救火。我见过很多扩容方案是“机器先加三台再说”其实先算一下在途并发往往能给出更精确的答案到底差 160 个并发位置加一台还是加两台心里有数。4.2 反向推算单机资源的极限和限流值反向用公式则是先看资源再看流量。单机线程池 200 个线程单个请求平均处理时间 50ms那这台机器的理论饱和吞吐是 200 ÷ 0.05 4000 QPS。注意这里的 50ms 必须是服务时间不是含排队的响应时间。实际部署不会顶着 100% 跑我一般按 60% 到 70% 的利用率留余量也就是 2400 到 2800 QPS 左右。这个数才是限流的参考基准而不是拍脑袋的“先限个 1000 试试”。如果目标是整体响应时间不超过 200ms那就把延迟下限也换算成流量上限设定系统能承受的在途并发为 300平均耗时要压在 200ms 内则入口 QPS 不应超过 300 ÷ 0.2 1500。注意这两个数回答的不是同一个问题一个是“资源吃不吃得消”一个是“延迟扛不扛得住”限流值应该取两者中更小的那个。4.3 多实例场景下不要只顾着乘水平扩容之后总并发容量近似单机容量乘以实例数但这个近似成立的前提是下游没有成为新的瓶颈。实例从 2 台扩到 5 台每台单机上限还是 2800 QPS全局限流值如果设成 14000那么后端每台分摊 2800刚好打满但如果数据库连接池只有 2005 台实例的请求在数据库侧形成 900 的在途并发数据库就率先排队整个系统其实被最弱的这一层卡住了。所以每加一层实例都要重新把公式套到所有下游上算一遍。网关的全局限流也要跟实例数联动否则扩了容流量还是进不来白花钱。多实例限流还有一个实测经验优先按单实例粒度做限流而不是只在网关搞一个全局值。单实例限流天然考虑到了机器数变化某台实例重启时其他实例的流量不会瞬间超过单机上限全局限流则更容易出现“总量没超但单机打爆”的情况。两种方案各有取舍但无论用哪种阈值都用上面的公式算别凭感觉。5. 几个真实故障现场复盘公式怎么帮我找到真凶5.1 场景一响应变慢但 CPU 不高某服务的监控显示 QPS 从 400 涨到 800平均耗时从 90ms 涨到 250ms但 CPU 只有 40%。不看公式的话很容易得出“机器性能够问题在下游”这种笼统结论。我把应用层和数据库层分别代入公式应用层在途并发 800 × 0.25 200刚好等于线程池上限 200说明线程已经打满数据库层在途并发 800 × 0.2 160但连接池上限只有 100。线程打满和数据库连接排队同时成立——真正的瓶颈是连接池太小大量线程在等连接释放CPU 自然闲。调整连接池到 200 之后同流量下平均耗时回落到 120ms 附近。整个过程没翻日志就靠两个乘法。事后复盘时我常感慨很多疑难杂症不是因为复杂而是因为我们没有把最基础的三个指标放在同一张纸上算账。5.2 场景二压测 QPS 上不去耗时却很低另一个项目压测时很诡异压测机开了 256 个并发连接QPS 死活只有 800平均耗时 5ms。套公式一算在途并发 800 × 0.005 4。一个只有 4 个请求在途的系统怎么可能代表 256 并发下的真实容量这明显是压测端自己喂不饱。检查发现压测脚本只用了单线程循环发请求大量连接根本没复用压测机 CPU 也被加解密占满了。换用高并发压测方式、关闭不必要的加密开销后同样 256 并发打出来 QPS 3200、平均耗时 65ms在途并发 3200 × 0.065 208和 256 接近数字才自洽了。所以压测结果异常时先怀疑压测端再用公式确认别急着给服务端加机器。这个场景我至少见过三次每次都是公式先暴露问题。5.3 场景三限流值拍脑袋定服务却闲着最后一个例子是最常见的限流阈值靠经验设成 1000 QPS流量高峰确实没超但服务端监控显示平时 QPS 只有 300平均耗时 30ms在途并发 300 × 0.03 9。一个线程池 200、单请求服务时间约 25ms、理论上限 200 ÷ 0.025 8000 QPS 的服务被一道 1000 的限流挡着用户高峰期大量请求被拒绝机器却在摸鱼。用公式重新推算资源上限按 70% 留余量是 5600按响应时间目标 100ms、在途并发上限 200 来算延迟约束下的流量上限是 200 ÷ 0.1 2000。取更小值 2000把限流值调过去之后同样的机器扛住了原来两倍的流量拒绝率降到零。限流不是“越小越安全”限流值离开公式计算就是在盲人摸象。用了几年下来我的固定习惯是看任何一份性能数据都先把 QPS、平均耗时、并发数这三个数对一遍账再谈优化方向。公式本身简单到不值一提难的是每次在混乱的监控曲线里想起它并且坚持用它把所有层的账都算平。你下次再为“系统能扛多少并发”发愁时不妨先坐下来把 QPS 和耗时乘一下。

相关新闻

Redis Cluster集群搭建实战:3主3从配置、故障转移与运维避坑指南

Redis Cluster集群搭建实战:3主3从配置、故障转移与运维避坑指南

1. 从单机到集群:为什么我们要折腾Redis ClusterRedis单机性能再强,也扛不住数据量持续膨胀和单点故障带来的双重压力。我见过太多项目一开始用单实例跑得好好的,业务量一上来,内存告警、主从切换失败、写入阻塞全来了。Redis Clu…

2026/10/12 21:47:48 阅读更多 →
BosonNLP情感词典实战:Python情感分析代码与避坑指南

BosonNLP情感词典实战:Python情感分析代码与避坑指南

简介:这份资源面向希望快速上手中文情感分析的开发者与数据科学学习者,提供了一套基于BosonNLP情感词典的完整示例代码,可用于舆情监控、评论挖掘、用户反馈分类等场景。代码流程覆盖读入BosonNLP情感词典与停用词表、用pandas读取.xlsx待分析…

2026/10/12 21:47:48 阅读更多 →
模板题与Special Judge:语义等价性与判定鲁棒性设计

模板题与Special Judge:语义等价性与判定鲁棒性设计

1. 为什么模板题和Special Judge不是“加个if判断”就能搞定的事在LPOJ这类在线判题系统里,很多人第一次接触“模板题”和“Special Judge”时,下意识会觉得:不就是让程序输出固定格式的字符串,或者写个校验函数比对答案对错吗&am…

2026/10/12 21:47:48 阅读更多 →

最新新闻

第6章:Spring AI 2.0 ChatClient 门面

第6章:Spring AI 2.0 ChatClient 门面

上章思考题答案 用户原话里的 {orderId} 若放进 SystemPromptTemplate 再渲染,StringTemplate 会把它当成变量。缺这个键时,ValidationMode.THROW 抛 IllegalStateException,正常咨询被拒绝。用户原话应走 UserMessage 或 ChatClient.user&a…

2026/10/14 0:03:43 阅读更多 →
【车载定位】基于扩展卡尔曼滤波 EKF,分别利用 TDOA、AOA 以及 TDOA+AOA 融合观测,搭配近恒速 NCV / 近恒位置 NCP运动模型对车辆轨迹估计附Matlab代码

【车载定位】基于扩展卡尔曼滤波 EKF,分别利用 TDOA、AOA 以及 TDOA+AOA 融合观测,搭配近恒速 NCV / 近恒位置 NCP运动模型对车辆轨迹估计附Matlab代码

✅作者简介:热爱科研的Matlab仿真开发者,擅长数学建模、数据处理、建模仿真、程序设计、完整代码获取、论文复现及科研仿真。🍎 往期回顾关注个人主页:Matlab科研工作室👇 关注我领取海量matlab电子书和数学建模资料 &…

2026/10/14 0:03:43 阅读更多 →
人工智能期末复习:用习题集构建考点地图,高效备考不挂科

人工智能期末复习:用习题集构建考点地图,高效备考不挂科

简介:这份资源汇集人工智能课程各章小结与经典习题解答,适合正在系统学习人工智能基础、准备期末考试的本科生或自学者使用。内容覆盖人工智能的概念与发展阶段、研究学派与研究领域、知识与知识表示(谓词逻辑、产生式规则、框架、语义网络&a…

2026/10/14 0:03:43 阅读更多 →
wandb-core 中的 Wire 依赖注入:从贡献指南到 go:generate 自动装配实战

wandb-core 中的 Wire 依赖注入:从贡献指南到 go:generate 自动装配实战

机器学习深度学习数据可视化可观测性 【免费下载链接】wandb The AI developer platform. Use Weights & Biases to train and fine-tune models, and manage models from experimentation to production. 项目地址: https://gitcode.com/gh_mirrors/wa/wandb 点…

2026/10/14 0:03:43 阅读更多 →
微博评论文本情感分析:从数据清洗到三模型对比的完整实践

微博评论文本情感分析:从数据清洗到三模型对比的完整实践

简介:面向毕业设计场景,资源围绕微博评论文本情感分析,完整覆盖支持向量机、朴素贝叶斯与AdaBoost三种机器学习算法的建模流程,适合计算机相关专业本科生用于课程设计或毕业设计参考。压缩包共70个文件,约6.05MB&#…

2026/10/14 0:03:43 阅读更多 →
小型超市仓库管理系统

小型超市仓库管理系统

小型超市仓库管理系统选题背景与意义 随着我国城镇化进程的不断推进以及居民消费水平的持续提升,小型超市作为连接城市社区与消费者的重要商业节点,在日常生活中的作用日益凸显。尤其是在一二线城市周边的居民区、城乡结合部及中小城镇,小型超…

2026/10/14 0:02:42 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →