用 Little‘s Law 把 QPS、平均耗时和并发数算成一本明白账

发布时间:2026/10/12 21:49:03

用 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 和耗时乘一下。
延伸阅读

更多相关文章

2026/10/12 21:44:03

Chrome插件开发实战:从MV3到商品信息抓取的全流程解析

简介:这是一款基于 JavaScript 开发的 Chrome 浏览器插件,主要面向需要从淘宝、京东商品详情页批量提取商品信息的电商运营、数据采集开发者;它能自动抓取商品标题、价格、优惠价格、主图及附图,并提交到预先指定的接口&#xff0…

2026/10/12 21:44:03

基于Python与Neo4j的知识图谱电影推荐系统:从三元组到RGCN实现

简介:面向毕业设计、期末大作业与课程设计场景,这份基于Python的知识图谱与图神经网络电影推荐系统是一套完整且经过验证的高分项目方案。项目以知识图谱为核心,对用户、电影、评分等数据构造实体关系网络,引入图神经网络完成特征…

2026/10/12 23:09:37

TensorFlow 2.1 Windows安装完全指南:CUDA与cuDNN踩坑全记录

过去两年里我帮好几个朋友解决过 Windows 下的 TensorFlow 安装问题,其中“TensorFlow 2.1”这个版本被提到的频率出乎意料地高。按道理它早就不是最新版了,但很多公司内部项目、老教材、开源仓库的依赖锁定文件里,都写着tensorflow-gpu2.1.0…

2026/10/12 23:09:37

华为OLT常用查询命令:故障定位与日常巡检指南

简介:这是一份华为OLT常用基本查询命令的实操文档,面向接入网运维工程师、装维人员及刚接触FTTH设备的技术人员,以MA5680T设备为对象,集中整理日常维护中的高频命令。文档按使用场景分类,涵盖ONU信息查询(d…

2026/10/12 23:09:37

计算机网络课程设计:电子图书馆网站的网络协议与部署实践

简介:《计算机网络》课程设计配套文档,围绕“电子图书馆网站设计”展开,面向网络工程、计算机及相关专业的学生,用于完成课程设计、巩固TCP/IP模型与组网知识。资料以1000M主干网、100M到点、至少4个子网为背景,完整呈…

2026/10/12 23:09:37

迷宫所有最短路径求解:反向BFS距离场与DFS剪枝实战

初看“pta-7-52 求解迷宫从入口到出口的所有最短路径(DFS)”这个题,很多人会觉得不就是个递归搜索嘛,结果动手一写就卡住了。其实这道题把DFS、回溯、剪枝、最短路预计算四个知识点全串在一起,而且“所有最短路径”这个要求,直接让…

2026/10/12 23:04:35

分库分表与多数据源切换的本质区别与协同落地

简介:本资源是一份基于Sharding-JDBC实现分库分表与多数据源动态切换的完整Java Web实战项目,面向中高级Java开发者及分布式架构学习者,聚焦高并发、大数据量场景下的数据库水平扩展痛点。项目以SSMDemo为载体,涵盖分片规则配置、…

2026/10/11 0:02:13

Python调用Gemini Structured Outputs实现工单路由门禁

客服工单最怕的不是模型“答错一句话”,而是它给出一段看起来合理的说明,程序却从中猜错优先级。通俗做法是:要求模型只交 JSON(JavaScript Object Notation,轻量数据格式),再让代码验证它。Gem…

2026/10/12 12:01:26

Spring Boot超市进销存系统毕设实战:从需求拆解到答辩通关

最近带的一个学生项目组里,有A同学跑来问我:选什么毕设题目最稳妥,既能让评审老师觉得工作量够,又不会在答辩时被问到语无伦次。我第一反应就是推荐基于Spring Boot的超市仓库管理系统——也就是超市进销存系统。这个题目乍一看平…

2026/10/12 12:54:07

Flutter StatefulWidget 生命周期核心解析

很多刚开始接触 Flutter 的朋友,在看完一堆“Hello World”和基础组件之后,大概率都会撞上同一堵墙:StatefulWidget 里那堆 initState、build、dispose 方法,到底什么时候被调用?为什么顺序是那样?在里面到…

2026/10/12 0:04:22

绝缘子缺陷检测数据集清洗与工业级训练实战指南

简介:本资源是面向电力AI研发人员、工业视觉工程师及智能巡检系统开发者的绝缘子缺陷检测专用YOLO格式数据集,解决无人机航拍场景下绝缘子破损、污闪、积雪等9类典型缺陷的精准识别与定位难题。数据集共2139张真实巡检图像(含训练/验证/测试集…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑