先别急着报数:搞懂 QPS 到底是什么?
大家好,我是牛哥。
做后端开发这些年,发现很多朋友在面试或工作中聊到QPS时,总容易陷入两个误区:要么张口报个 "几百上千" 的数字,却讲不清数字来源;要么把 QPS 和 TPS、并发数混为一谈,被追问几句就卡壳。
其实面试官问 QPS,就像聊天时问 "你最近项目忙吗",不是要个忙或者不忙的答案,而是是想听听背后的细节 - 数字怎么来的?和业务匹配吗?遇到过哪些问题?
今天牛哥就把这些内容梳理出来,帮你彻底弄懂QPS,把日常工作里的经验,变成面试时的加分项。
先别急着报数:搞懂 QPS 到底是什么?
当面试官抛出"你的系统QPS是多少"这个问题时,很多人的第一反应是在脑海里搜寻一个数字。但是相信我,一个孤立的数字几乎毫无意义。在给出任何答案之前,我们必须先确保自己真正理解这个问题的核心 — QPS 究竟是什么。
一句话说清QPS
简单来讲,QPS = Queries Per Second,即每秒查询数,每秒查询数是衡量一个系统处理请求能力最直观的指标。
想象一下,你的系统就像一家繁忙的餐厅,QPS 就是每分钟走进餐厅的顾客数量。这个数字直接反映了餐厅的受欢迎程度和潜在的营收能力。
但这里的 "查询" 是一个广义的概念,不只局限于数据库的查询指令。你刷新闻时下拉刷新、搜商品时点击搜索、给动态点赞,这些操作背后,App 或浏览器向服务器发起的每一次请求,本质上都是 "查询",而 QPS 正是统计这类查询每秒发生次数的核心指标。
不过,正因为"查询"的范围广,很多人在聊系统性能时,容易把 QPS 和另外两个常被提及的指标 — TPS和并发数弄混淆。其实这三个指标各有各的关注点
QPS 和 TPS、并发数的 "核心区别"
我们用一个表格来清晰地对比一下:
| 指标 | 全称 | 核心关注点 | 通俗理解 |
|---|---|---|---|
| QPS | Queries Per Second | 请求的频率 | 餐厅每分钟进来多少位顾客 |
| TPS | Transactions Per Second | 业务的完整性 | 餐厅每分钟能完整地服务完多少桌客人(从入座到结账离开) |
| 并发数 | Concurrency | 系统的容量 | 餐厅里同时有多少桌客人正在用餐 |
看完表格,我们再结合实际场景,看看每个指标是如何落地应用的。
先看 QPS(每秒查询数),它核心盯的是请求的数量和速度,只要客户端比如手机 App、浏览器,向服务器发了请求,不管这个请求是干做什么的,都算做一个请求。
就像你打开电商商品详情页时,浏览器不会只发一个请求:它会单独请求商品的基本信息,要拉用户评价列表,还要加载相关推荐商品。
这一套操作下来,假设发了 10 个独立请求,自然也就贡献了 10 个 QPS。
再说说 TPS(每秒事务数),它和 QPS 最大的不同,是更看重业务逻辑的完成度。一个 "事务" 不是孤立的单个请求,而是一组存在先后执行顺序的操作集合,这一系列操作必须全部执行完毕,整个 "事务" 才算完成。
比如网购下单支付这个 "事务",需要拆成 5 个独立的请求才能完成:
请求1:查看目标商品库存是否充足;
请求2:在系统中创建订单记录;
请求3:扣减对应商品的库存数量;
请求4:向支付系统发起支付请求;
请求5:根据支付结果更新订单的最终状态。
只有这一整套步骤全部执行完成,才能算作一个完整的 TPS,但这 1 个事务同时贡献了 5 个 请求,也就是5 个 QPS。
因此在通常情况下,一个事务会包含多个独立请求,系统的 TPS 会小于或等于 QPS。
最后是 并发数,它关注的是同一时间点,系统正在处理的请求有多少。
这里的正在处理是关键 — 它既不统计已经处理完的请求,也不统计还没开始处理、在排队的请求,只盯着当下正占用系统资源、处于处理中状态的请求数量。
以外卖场景为例:饭点 12 点,你常用的外卖 App 有 1500 个用户同时点 "查看附近商家",这些请求会同步发送到外卖平台的服务器。若服务器同一时间能 "分心处理" 300 个请求,那此时系统的并发数就是 300。
但同样是300 并发,随着 "查看商家" 请求的处理难度不同,对应的 QPS 会完全不同,两者 "一高一低" 的差异也会更清晰:
如果这类请求需要复杂计算,1500 个请求得 15 秒才能处理完,每秒仅能接收 100 个请求,即 QPS=100。这种情况下,QPS 虽低,但 300 个并发已让服务器算力饱和,属于高并发场景;
可如果这类请求只需简单查询、处理速度极快,每秒能处理 3000 个请求,1500 个请求仅需 0.5 秒就全处理完,几乎没有排队。此时 QPS 虽高,但 300 个并发远没到服务器承载上限,用户点击后能秒出商家列表、完全感受不到延迟,属于低并发场景。
可见,QPS 的高低看的是每秒请求总量,并发数的高低看的是同一时间实际处理的请求量,高并发不等于高 QPS,二者完全可能呈现反向关系,不能混为一谈。
而在理解了两者差异后,我们也需要意识到:脱离系统本身的定位谈 "QPS 高不高" 没有意义。我们要回归到实际场景,结合系统定位来判断。
不同系统QPS的合理范围
按系统类型划分,我们能清晰地看到不同场景下的 QPS 合理区间:
- 小型内部系统 — 够用就好
像公司 OA、部门数据报表平台这类系统,合理 QPS 在日常 10-50、峰值 100-300 就够了。它们的用户规模只有几十到几百人,平时无非是提交日报、查看报表这类简单操作,对响应速度要求不高。
2.电商详情页接口 — 扛住突发流量
像商品介绍、实时库存查询这类电商接口,合理 QPS 要按场景分:日常维持在 5000-20000,到了 618、双 11 大促就得扛住 20 万 - 50 万的 QPS。毕竟这类接口用户能达百万、千万级,大促时大家集中抢货、刷库存,流量会暴涨 10 倍以上。
3.支付核心接口 — 优先保稳定
订单付款、退款对账这类支付核心接口,合理 QPS 是日常 1000-5000,峰值 1 万 - 3 万。作为金融级场景,它们的核心不是 "快",而是 "稳",哪怕峰值时响应慢一点,也得优先稳住系统。
4.工具类接口 — 重成功率
短信发送、验证码验证这类工具类接口,合理 QPS 不用太高:日常 100-500,峰值 1000-2000 就够了。它们的用户使用场景很分散,比如注册收验证码、活动发通知,核心是保证送达率,而不是单纯提升处理速度。
不过这些区间终究是参考,实际的面试和工作中不能只靠对标的范围下判断,我们必须要拿到系统真实运行时的 QPS 数据,才能准确判断当前性能是否够用、要不要优化。
接下来,我们就聊聊怎么拿到真实的QPS。
拿到真实的QPS
要获取系统真实的 QPS,主要有三种方法,第一种生产环境监控,是最核心、最能反映系统实际运行状态的方式,也是面试中高频考察的重点。另外两种,压测工具和手工估算则作为补充,用于验证或快速估算。
方法一:生产环境监控
这种方法通过多维度监控生产系统的实际运行数据,是实际工作中最常用的方式,它的逻辑是 "先统计 QPS→再验证真实性",具体分两步展开:
应用层:直接看接口 QPS
应用层是 QPS 的直接发源地,所有用户操作,比如点击商品、提交订单最终都会转化为接口请求,因此在这里统计 QPS 最直接。
第一种:日志收集与可视化分析
适合已有完善日志体系的系统。核心思路是先记录请求日志,再提取关键信息统计,最常用的工具组合是 ELK Stack,也就是 Elasticsearch + Logstash + Kibana 的组合。具体流程是:
- 先在接口代码中打印请求日志,日志里要包含接口路径、请求时间、请求 ID 等信息,比如 Java 项目中用 Logback 输出日志文件;
- 然后通过 Logstash 读取日志文件,按预设规则解析数据,比如按 "接口路径" 分组、按 "请求时间" 格式化;
- 解析后的数据会存入 Elasticsearch;
- 最后在 Kibana 中创建可视化图表,按 "每秒" 为时间粒度统计每个接口的请求次数。
这样就能直观看到每个接口的实时 QPS,还能回溯历史 QPS 波动,比如查看昨天 12 点的峰值。
第二种:APM 工具自动追踪
适合追求 "零侵入统计" 的场景,例如 SkyWalking、Pinpoint、Zipkin 这类 APM(应用性能监控) 工具。它们的核心优势是不需要在业务代码中额外写统计逻辑,只需在项目中引入对应的探针。
引入探针后,工具会自动拦截所有接口调用,记录请求时间、接口名称等信息,并在自带的控制台中展示 QPS。
比如用 SkyWalking 时,进入服务接口页面选择 QPS 指标,就能看到每个接口的实时 QPS 曲线,还能对比不同接口的 QPS 占比,方便快速定位核心接口,比如判断商品查询接口 QPS 是否占比最高。
第三种:自定义埋点统计
适合需要精准控制统计范围的场景,比如只统计核心业务接口。这种方式需要在接口代码中嵌入简单的统计逻辑,核心是用 "计数器 + 时间窗口" 计算每秒请求量。
以 Golang 的 Gin 框架为例,可按三步轻量实现:
首先定义 QPS 计数器结构体与初始化方法
import (
"sync/atomic"
"time"
"github.com/gin-gonic/gin"
)
type QPSCounter struct {
requestCount int64 // 累计请求数
qps int64 // 每秒QPS结果
}
// NewQPSCounter 初始化计数器,启动每秒统计任务
func NewQPSCounter() *QPSCounter {
c := &QPSCounter{}
// 定时任务:每秒计算1次QPS
go func() {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()
for range ticker.C {
// 原子交换:获取过去1秒请求数,同时重置计数
count := atomic.SwapInt64(&c.requestCount, 0)
// 存储当前QPS
atomic.StoreInt64(&c.qps, count)
}
}()
return c
}接着在核心接口中埋点统计请求,每次请求触发计数 + 1
func main() {
r := gin.Default()
// 初始化商品查询接口的QPS计数器
goodsQPS := NewQPSCounter()
// 核心业务接口:商品查询(埋点统计)
r.GET("/api/goods/query", func(c *gin.Context) {
// 每接收1次请求,计数+1(原子操作避免并发问题)
atomic.AddInt64(&goodsQPS.requestCount, 1)
// 实际业务逻辑(简化)
c.JSON(200, gin.H{"goods_id": 1001, "name": "示例商品"})
})
}最后,写一个简单的接口查看实时 QPS,方便对接监控面板或直接调用查看。
func main() {
// (接步骤2代码)
// 监控接口:查看商品查询接口的实时QPS
r.GET("/api/monitor/qps", func(c *gin.Context) {
// 原子读取当前QPS,避免并发读取问题
currentQPS := atomic.LoadInt64(&goodsQPS.qps)
c.JSON(200, gin.H{"goods_query_qps": currentQPS})
})
// 启动服务
r.Run(":8080")
}这样就能精准统计核心接口的 QPS,整体没有额外的依赖,还能根据需求扩展,比如只统计成功响应的请求、按用户地区区分统计等。
系统层监控:验证 QPS 是否可信
光看应用层的 QPS 还不够,有时会出现应用层显示 QPS 很高,但系统却很空闲的情况,比如日志统计错误、重复计数,这时候就需要通过系统层监控验证 QPS 的 "可信度"。核心逻辑是:
真实的高 QPS 一定会消耗系统资源,若资源消耗与 QPS 不匹配,说明统计数据可能有问题。
服务器资源监控是最基础的验证维度,重点关注 CPU、内存、网络 IO 这三个指标。在企业级监控实践中,Prometheus + Grafana 是当前最主流、最常用的技术组合。
用它监控 Linux 服务器时,能直观对比资源消耗与 QPS 的匹配度:
若应用层显示 QPS 达到 5000,但 CPU 使用率仅 10%、内存占用不到 30%,且网络 IO 也很低,那大概率是 QPS 统计有误;
反之,若 QPS 升高时,CPU 使用率持续超过 80%、内存占用稳步上升,且网络 IO(接收 / 发送字节数)同步增长,说明 QPS 数据基本可信。
因为每处理一个请求,都会消耗 CPU 计算资源,也会产生网络数据传输,这种资源与 QPS 的联动关系,正是验证数据真实性的核心依据。
其次是数据库监控,尤其是依赖数据库的接口。常用的数据库监控工具是: Prometheus + mysqld_exporter 用于 MySQL 监控,Prometheus + pg_exporter 用于 PostgreSQL 监控,通过这类组合能直接获取数据库 QPS、连接数、慢查询数量等指标。
验证逻辑也很直接:
若应用层显示订单创建接口 QPS 为 1000,但数据库 QPS 仅 200 且连接数无明显增长,大概率是应用层统计有误;
而当接口 QPS 从 500 增至 1000 时,数据库 QPS 也从 800 涨到 1600,连接数同步从 50 升到 100,这种趋势匹配就说明 QPS 真实。
毕竟接口请求最终会转化为数据库操作,两者变化本应正相关。
最后是网络监控,关注带宽使用率和网络延迟。企业常用 Zabbix 或 Nagios 监控服务器网卡,通过实际数据匹配度判断 QPS 真实性:
若接口 QPS 很高,但服务器带宽使用率仅 20%,假设带宽是 100Mbps,且没有丢包,可能是接口返回数据量太小,比如只返回 JSON 字符串,这种情况下 QPS 统计可能存在偏差。
因为高请求量本应伴随一定的带宽消耗,过低的带宽占用与高 QPS 不匹配;
通过应用层统计QPS,系统层验证QPS的可信度,我们了解了生产环境监控的核心逻辑。但是生产环境监控只能反映当下的实时 QPS,没法提前预判系统能扛住的最大承载上限。
比如大促峰值流量来临,系统会不会被压崩;也难验证性能优化后的实际效果,像加了缓存后 QPS 具体能提升多少。
这个时候,压测工具就派上用场了。
它通过模拟高并发场景,既能测出系统的极限 QPS,也能定位优化前后的性能差异,进而为容量规划、大促准备提供依据。
方法二:压测工具实测
压测工具的核心价值,就是通过模拟高并发请求复现极端流量场景,帮我们测出系统 QPS 的极限。市面上的压测工具有很多种,不过不同工具的特性、功能复杂度和适用场景差异较大,需要结合实际需求选择。
我们重点介绍 JMeter、wrk、Locust 这三款主流工具,它们覆盖了从 "复杂全链路压测" 到 "轻量快速验证" 再到 "高度定制化测试" 的绝大多数场景,能满足不同团队的核心需求。
- 全能型:JMeter
JMeter 作为压测领域的 "国民级工具",几乎是所有性能测试场景的基础选项。它支持 HTTP 接口、数据库、消息队列等 20 多种协议,既能测单个接口的 QPS,也能模拟 "登录→加购→下单" 这类全链路业务流程。压测后会生成包含 QPS 趋势图、响应时间分布、错误率占比的详细报告,帮我们精准定位瓶颈 —— 比如从 "90% 响应时间超 3 秒" 判断系统性能不达标,或是从 "数据库请求耗时占比 80%" 锁定优化方向。
适合电商大促全链路压测、金融支付系统多流程验证等复杂且需深度分析的场景
- 轻量高效型:wrk
如果只是想快速验证某个接口的性能,那 wrk 就是最高效的选择。这款基于 Golang 开发的工具,主打 "轻量、高效、零配置":一行命令就能发起压测并输出 QPS、响应时间等核心指标。
例如通过 10 个线程、维持 1000 个并发连接,对商品接口持续压测 60 秒的命令如下:
wrk -t 10 -c 1000 -d 60s http://localhost:8080/api/goods不过 wrk 的定位很明确 —— 它是 "开发者的随手测工具",不支持复杂业务流程模拟,也没法生成详细的可视化报告。
适合开发阶段的高频次、轻量化验证,比如测试数据库索引优化后的接口响应速度,或是快速对比不同版本接口的 QPS 差异。
- 定制化压测型:Locust
这款压测工具代表了 "以代码驱动压测" 的主流方向,开发者可以通过脚本自由控制请求参数 —— 比如随机生成商品 ID、动态拼接用户 Token;
也能灵活定义用户行为,像新用户只浏览商品,老用户直接下单;
甚至能结合业务规则设置流量模型,例如前 10 分钟流量从 100 QPS 逐步增长到 1000 QPS,完全贴合真实业务场景的复杂需求。
适合社交平台的 "点赞 / 评论 / 转发" 混合接口压测,或是跨境电商的 "多地区用户访问延迟模拟" 这类非标准化场景,体现工具的定制化能力,尤其受 Python 技术栈团队青睐。
基于上面的介绍,我们发现无论是生产环境监控的实时 QPS 统计,还是压测工具对极限 QPS 的实测,都需要依赖一定的技术工具或系统支持。
但如果只是想快速粗略判断 QPS 范围,用最基础的手工估算就能满足需求。
方法三:最基础的手工估算
手工估算的逻辑非常简单,核心公式就是 QPS = 总请求数 / 时间窗口,只需找到两个关键数据 ——"某段时间内的总请求量" 和 "对应的时间长度",就能快速算出平均 QPS。
比如日常业务中常见的场景:
- 某接口 1 小时内处理了 36 万次用户请求,按公式计算:QPS = 360,000(总请求数) / 3600(1 小时换算成秒) = 100,即该接口平均 QPS 约为 100;
- 某活动页面 3 分钟内有 1.8 万用户点击访问,QPS = 18,000 / 180(3 分钟换算成秒) = 100,平均 QPS 同样为 100。
这种方法的优势是零门槛、无需任何工具,通常作为前期做容量规划、或没有工具支持的临时场景。
通过以上三种方法,我们可以拿到系统的 QPS,但是拿到 QPS 并非最终目的,更重要的是解读它,让数字转化为指导业务和系统优化的有效信息。
拿到 QPS 之后:更重要的是 "解读" 它
解读 QPS 的关键在于建立一套连贯的解读逻辑:理解数字背后的业务含义 → 发现系统潜在问题 → 制定优化方案 → 应对突发情况。这四步循序渐进、相互支撑。
第一步:让 QPS 落地业务,让数字有实际意义:
拿到 QPS 的第一反应不该是 "这个数字高不高",而是 "这个数字对业务有什么用"。脱离业务的 QPS 毫无意义。
比如电商的商品查询接口 QPS 再高,若订单接口 QPS 没跟上,说明用户 "只看不买",高 QPS 反而暴露了转化问题;
反之,若两者同步增长,才证明流量真的带动了业务。
同时还要关注 "健康度":高 QPS 若伴随高错误率(比如支付接口 QPS 上涨但超时订单变多)、慢响应(比如 QPS 没到上限但用户反馈加载慢),这样的数字不仅没价值,还可能导致用户流失。
同时还要关注 "健康度":高 QPS 并非绝对是好事,如果支付接口 QPS 上涨的同时超时订单变多,说明高错误率正在消耗业务价值;如果 QPS 还没到系统上限,用户却反馈页面加载缓慢,意味着慢响应正在损害用户体验,需要立即优化。
通过落地业务,我们明确了系统在正常业务负载下的"正常 QPS 范围",那么当 QPS 出现异常变化时,这往往是系统出现问题的强烈信号。
第二步:从 QPS 变化里,发现系统 "异常信号"
QPS 的异常通常表现为突然暴跌、骤升或呈现剧烈波动,例如:
当平时稳定在 1000 的接口 QPS 突然降至 100,大概率是系统内部出现严重问题。
- 接口代码层面,可能因逻辑设计缺陷形成死锁,导致请求处理流程停滞;
- 数据库连接池方面,如果配置不合理,或者应用存在连接泄漏问题,就会出现连接池耗尽的情况。
- 缓存方面,可能因大量缓存同时失效即缓存雪崩,原本依赖缓存的请求一股脑全部涌向数据库,数据库瞬间被高并发请求压垮,处理能力大幅下降,对外呈现为接口 QPS 骤降。
- 而网络故障、负载均衡器异常,会使得请求无法顺利抵达服务器,服务器处理的请求量锐减,QPS 也就随之暴跌。
这些异常本质上是系统通过 QPS "传递求助信号":要么是处理能力下降,具体表现为 QPS 下跌,比如原本稳定的 QPS 突然大幅回落;要么是压力过载,通常伴随 QPS 骤升且响应时间恶化,比如流量暴涨的同时接口变慢。
及时捕捉这些信号,才能在小问题扩大前介入,避免故障蔓延。
第三步:用 QPS 指导系统 "性能优化",不盲目加服务器
发现异常或明确性能目标后,需要结合 QPS 表现针对性优化。这一步要避免盲目扩容,而是让 QPS 成为 "问题导航仪"。
针对第二步中的异常场景,优化思路也各有侧重:
- 若 QPS 暴跌源于 "接口代码死锁",需要优先排查代码逻辑,通过日志定位死锁产生的代码块,优化锁的获取与释放顺序,或减少不必要的锁竞争;
- 若因 "数据库连接池耗尽" 导致 QPS 下跌,可以先检查连接池配置(如最大连接数是否过低),调整参数匹配业务请求量,同时排查应用是否存在连接未释放的泄漏问题,避免连接资源被浪费;
- 如果是 "缓存雪崩" 引发 QPS 骤降,可采用缓存过期时间随机化、添加本地缓存作为兜底、给数据库加读写锁或队列削峰等方式,减轻数据库压力,恢复 QPS 至正常水平;
- 若 QPS 骤升且响应恶化,如遭遇恶意请求或逻辑重试,先通过Sentinel、Nginx 等限流工具限流,拦截异常流量,再修复重试漏洞,避免无效请求占用资源;
当然如果没有明显异常,但是QPS 已接近系统上限、响应时间持续变长的情况,也需先精准判断瓶颈。
如果是单请求处理效率低,比如 QPS 仅 200 但单次请求耗时长达 3 秒,就优先从代码和数据库入手优化;如果是系统整体承载能力不足,比如单请求耗时正常,但 QPS 一涨响应就变慢,再考虑扩容服务器,避免盲目加资源造成浪费。
解决了当下的问题,还要用 QPS 预判未来的风险。
第四步:基于 QPS 预判风险,提前准备应对策略
像大促、直播带货这类可预期的突发场景,流量往往会远超日常,若等到流量涌来再应对,很容易手忙脚乱。这一步不用复杂操作,结合历史 QPS 数据和业务规划,分两点做好准备:
第一点是推算峰值 QPS,明确系统需要扛住的压力上限。核心是一个简单公式:
峰值 QPS = (预期用户数 × 平均请求频率)× 峰值系数。
比如大促期间,我们预计会有 20000 名用户同时在线,根据过往业务经验,每个用户平均 1 分钟内会发起 4 次请求,包括搜索商品、加购、下单等操作,先算出预期 QPS=20000×(4÷60)≈1333;
但大促零点流量会集中爆发,参考历史数据,峰值流量通常是均值的 3 倍,所以再乘以 3,最终得到峰值 QPS≈4000,这就是系统需要应对的极限流量目标。
第二点是提前验证和做足准备,确保系统能扛住峰值压力。
先使用常用的压测工具如 JMeter,模拟 4000 QPS 的流量对系统进行测试,重点观察两个关键指标:
- 响应时间是否能稳定在用户可接受的范围,比如 200ms 以内;
- 错误率是否控制在合理标准内,不出现大量请求失败的情况。
如果测试不达标,就提前启动优化,比如扩容服务器、升级缓存集群。同时还要制定应急方案:
给核心接口设定好限流阈值,比如 QPS 超过 4000 时自动拦截部分非关键请求;
准备好降级策略,比如暂时关掉商品推荐这类非核心功能,就算流量比预期还高,也能优先保障下单、支付这些核心业务正常运行。
这一步将 QPS 从 "问题诊断工具" 升级为 "风险预警器",让系统在流量高峰前有备无患。
以上四步,从判断业务价值到捕捉异常,从精准优化到提前布局,层层递进,形成了完整的 QPS 解读闭环,最终让 QPS 真正成为系统性能和业务健康的 "晴雨表"。
写在最后:让 QPS 成为技术与业务的 "桥梁"
看到这里,相信大家对 QPS 的认知已经不止于 "一个性能数字"—— 从如何通过监控、压测、手工估算获取 QPS,到用四步逻辑解读其背后的业务价值与系统状态,我们其实是在构建一套 "用数据驱动决策" 的思维。
QPS 既不是越高越好的 "面子数字",也不是单纯衡量性能的 "技术指标",而是连接技术优化与业务增长的核心桥梁。
