想象一个繁忙的十字路口:交警站在中央,不仅要看有多少车通过,更要判断路口会不会堵死、什么时候达到极限、需要提前多久疏导车流。AI推理服务也是一座“数字路口”——模型是路面,GPU是车道,而吞吐量监控就是那位站在高处的交警,不断清点“单位时间里有多少请求顺利通过”。没有这位交警,系统就像无标识的路口:车多了就堵,堵了才发现,发现时用户已经骂声一片。吞吐量监控便是这样一门“数车流的学问”:它告诉我们系统的处理能力边界在哪里,何时该扩容,何时能放心压榨每一分算力。

岗位关联

吞吐量监控是AI运维的“仪表盘”——掌握它,你就能精准回答“系统到底能扛多少QPS”这一灵魂拷问,为资源投入和容量规划提供数据支撑,是AI工程化落地能力的关键一环。

目录
  1. 可视化演示
  2. 吞吐量定义与单位
  3. 采集方案设计
  4. QPS与TPS区别
  5. 瓶颈分析与定位
  6. 容量规划与水位
  7. 监控三域模型
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

动态演示吞吐量监控的核心机制,通过开始/执行/监控/完成四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

吞吐量监控:吞吐量指 吞吐量指标的基本定义与衡量维度 QPS与TPS指标的区别与应用 核心机制可视化 吞吐量监控整体架构与关键组件

吞吐量定义与单位

十字路口的交警首先要回答一个最基础的问题:“这片区域到底能过多少车?”他需要先界定“一辆车”是什么意思——是轿车还是货车?“单位时间”是每分钟还是每小时?同样,吞吐量监控的第一步,就是给“通过能力”一个精确的定义:在单位时间内,系统成功处理的请求数量。这个定义看似简单,却是一切监控的基石——如果连“数什么”都没说清,后面的统计都会失真。

在AI推理服务的语境里,吞吐量的核心指标是QPS(Queries Per Second),即每秒处理的请求数。但经验丰富的运维知道,仅仅看一个QPS数字是不够的:系统在空闲时能跑出漂亮的高峰,在持续压迫下却可能大幅下滑。因此工程上区分两个关键口径——稳态吞吐量(系统在持续压力下能稳定维持的处理速率)和极限吞吐量(系统在资源耗尽前能冲击的最大速率)。这就好比一条城市主干道,畅通时能每分钟通过60辆车,但早晚高峰持续拥堵时实际只能稳定通过40辆——稳态吞吐量才是容量规划真正需要的数字。

回到路口的画面:交警最终在报告上写下的不是“刚才有段路很通畅”,而是“这条路平均每小时稳定通过2200辆车”。有了这个数字,城市规划者才能决定要不要拓宽道路。

稳态吞吐量=持续负载下成功完成的请求总数持续工作时间(秒)\text{稳态吞吐量} = \frac{\text{持续负载下成功完成的请求总数}}{\text{持续工作时间(秒)}}
这个公式在说:别被瞬时高光迷惑,要统计的是“长时间扛压”后系统还能稳定交付的速率。
  1. 分子——持续负载下成功完成的请求总数这里强调两个限定词。“持续负载”意味着压测或监控必须维持一段稳定压力,而不是只测几秒钟就收工——像堵车时连续数10分钟车流,而不是只数一个绿灯;“成功完成”则要求只统计HTTP 200或有业务响应的请求,超时和报错的不算数,因为那些是“没通过路口就掉头回去的车”。
    成功数=总请求数−失败数−超时数\text{成功数} = \text{总请求数} - \text{失败数} - \text{超时数}
  2. 分母——持续工作时间统计的时间窗口必须足够长且连续。如果窗口内压力忽高忽低,算出来的“平均吞吐”会失真——好比你一天里只挑了凌晨3点车最少的时候数车流,得出的结论自然不能代表白天。工程上通常取5分钟、15分钟或1小时作为统计窗口。
    Δt=t结束−t开始\Delta t = t_{\text{结束}} - t_{\text{开始}}
  3. 计算——除法把成功数量除以时间,得到的就是“每秒钟能稳定交付多少请求”的速率。这个值越大,代表系统的“路面越宽”。
    TP稳态=N成功Δt\text{TP}_{\text{稳态}} = \frac{N_{\text{成功}}}{\Delta t}

采集方案设计

要数车流,交警得先决定站在哪儿数。如果站在路口中央数,能数到每一辆车的到来;如果站在匝道口数,只能数到进入主路的车——两个位置的数字含义完全不同。吞吐量采集方案的核心,就是回答“在哪个环节、用什么方式数请求”的问题。

第一层是网关层采集。在Nginx、API Gateway这类入口处部署全量计数器,统计进入系统的所有HTTP请求。这一层的优势是“一口收口”——所有流量必经此处,数字最完整,且不侵入业务代码。就像在路口安装地磁感应线圈,每过一辆车自动触发一次计数。第二层是应用层埋点。在推理服务内部Pipline的关键路径(如预处理、模型推理、后处理)埋入埋点计数器,统计各阶段处理量。这能回答“请求进来之后,内部到底处理了多少”,好比在路口内的每条车道上都装上探头,看清车流在路口内部是如何分布的。

采集到裸计数器后,还需要解决滑动窗口统计的问题。计数器本身只是“从启动到现在累计数”,但监控需要的是“最近5分钟每秒多少请求”。工程实践上采用滑动窗口:维护一个时间轮,每个时间片(如1秒)一个计数器,窗口滑动时新片加入、旧片丢弃。阿里、腾讯的监控系统均采用类似机制。此外还要做采样与聚合:对海量监控数据,按分钟级粒度聚合成平均值/最大值/P99,减少存储开销。

回到路口画面:交警不再傻站着数一天,而是每5秒瞄一眼滑动窗口,动态播报“最近5秒平均每秒过车X辆”。这种“滚动统计”既灵敏又稳定,正是采集层设计的精髓所在。

吞吐量(t)=∑i=t−5stcounti5\text{吞吐量}(t) = \frac{\sum_{i=t-5s}^{t} \text{count}_i}{5}
滑动窗口公式的含义是:把过去5秒内每秒钟的请求数加起来除以5,得到的均值就是“此刻的瞬时QPS”。它在不断滚动更新,和路口交警每5秒报一次“最近5秒过了多少车”是一个道理。
  1. 时间片计数器 count_i系统把时间切成一个个等长的小格子(例如每格1秒),每一格内记录完成的请求数量。这是滑动窗口的“原子单位”,就像交通摄像头每秒拍一张照片,数清这一秒内通过的车。
    counti=第 i 秒内完成的请求数\text{count}_i = \text{第 } i \text{ 秒内完成的请求数}
  2. 滑动窗口求和把当前时刻向前数5个格子(5秒)的计数器全部相加,得到“最近5秒的总请求数”。窗口每过1秒就整体向前挪一格,所以叫“滑动”——交警的统计口径始终是“最近的5秒”,而不是“过去任意5秒”。
    total=∑i=t−4tcounti\text{total} = \sum_{i=t-4}^{t} \text{count}_i
  3. 除以窗口时长求和结果除以窗口宽度(5秒),得到每秒平均速率。这个均值比瞬时值平滑,能有效消除偶发毛刺——好比肉眼数车容易受红绿灯周期影响,摊到5秒平均后更反映真实通过能力。
    QPS=total5\text{QPS} = \frac{\text{total}}{5}

QPS与TPS区别

路口交警有时候会被问到一个刁钻问题:“你数的车,是过路口的车次数,还是从A点到B点完成了一整段行程的车辆数?”前者只要车轮碾过路口就算一次,后者要求车辆完整通过整条监控路段才算完成——这就是QPS与TPS(Transactions Per Second)的本质区别。

QPS(Queries Per Second) 以“一次请求”为计量单位。每个HTTP请求就算一次QPS,无论这个请求内部是简单查询还是复杂推理。TPS(Transactions Per Second) 以“一个完整事务”为计量单位——事务可能包含多个请求、多次状态变更。例如一个在线翻译功能,用户点击“翻译”后前端可能连续调用3次后端接口(分词、翻译、校对),对网关来说是3次QPS,但对业务来说这只是一个完整的“翻译事务”,即为1次TPS。

工程上如何选择?核心看统计口径服务于什么目的。如果关注的是基础设施承载压力(网络带宽、连接数、CPU),选QPS——每个请求都会消耗连接和算力资源,好比每辆经过的车都需要占用路面空间;如果关注的是业务价值交付量(用户完成多少次翻译、多少次图像识别),选TPS——只有完整走完流程的用户才算真正“到达目的地”。AI推理场景中,一个典型的对话请求可能包含多轮内部调用,此时TPS更能反映“业务层面系统真正完成了多少有效工作”。

回到路口的画面:如果交警向政府报告“每小时通过2万辆车”(QPS),市长并不能直接知道“有多少市民完成了通勤”(TPS)。对于AI服务,架构师需要同时看两个数字:QPS告诉你系统吃不吃得消,TPS告诉你用户任务是否顺利完成——两者缺一不可。

吞吐量={QPS=每秒完成的请求数TPS=每秒完成的事务数\text{吞吐量} =\begin{cases}\text{QPS} = \text{每秒完成的请求数} \\\text{TPS} = \text{每秒完成的事务数}\end{cases}
这条公式的意义在于:QPS和TPS是同一座路口的两种“数法”——数一辆辆过路的车(请求),还是数一个个完整到达目的地的旅程(事务)。
  1. QPS定义——每秒完成的请求数这是最常用的吞吐量单位。对AI推理服务,一个“请求”通常就是一次对HTTP接口的调用。它直接反映了系统承受访问压力的能力,是容量规划中最基础的计量方式。
    QPS=总请求数时间(秒)\text{QPS} = \frac{\text{总请求数}}{\text{时间(秒)}}
  2. TPS定义——每秒完成的事务数一个事务在AI场景中往往包含多次请求。例如一个“证件照抠图”业务,从用户上传图片到返回结果可能需要1次图片上传请求 + 1次AI处理请求 + 1次结果回传请求,这3个请求共同构成1个“抠图事务”。TPS统计的是完整闭环的次数。
    TPS=总事务数时间(秒)=总请求数/每事务请求数时间(秒)\text{TPS} = \frac{\text{总事务数}}{\text{时间(秒)}} = \frac{\text{总请求数} / \text{每事务请求数}}{\text{时间(秒)}}
  3. 换算关系——TPS = QPS / 每事务请求数当已知一个事务平均由K个请求组成时,QPS与TPS之间可以换算。但K值会因用户行为模式变化而波动(有的用户一次只做1次,有的做5次),所以严格换算并不总是可靠,实际监控时应当明确标注口径。
    TPS=QPSKavg(Kavg=每个事务平均请求数)\text{TPS} = \frac{\text{QPS}}{K_{\text{avg}}} \quad (K_{\text{avg}} = \text{每个事务平均请求数})

瓶颈分析与定位

车流不畅时,交警的第一反应不是责怪司机,而是查找堵点:是路口信号灯太短?还是某条车道施工?还是转弯车辆与直行车互相抢道?吞吐量监控的瓶颈分析有同样的逻辑——当QPS上不去时,要找出“拖住整个系统的那个红灯”。

第一步是逐层耗时分析。把一次请求的生命周期拆成网络传输、排队等待、模型推理、结果返回等阶段,分别统计平均耗时和P99耗时。这就像把一段通勤路线拆成“走到地铁站—等车—坐车—出站”四段,用计时器分别记录哪一段花的时间最多。第二步是识别等待与空闲。高吞吐系统的关键在于“让所有部件尽量都忙着”。如果CPU利用率很低但QPS上不去,说明系统在等待外部资源(如磁盘IO、数据库锁、下游接口响应);如果CPU高但QPS也不高,说明计算本身太重——好比路口明明车不多却堵成一团,原因是每辆车过路口时都要磨蹭半天。

第三步是定位热源与争抢。在GPU推理集群中,最常见的瓶颈点是:GPU利用率是否打满、显存带宽是否争抢、CPU预处理/后处理是否阻塞、锁竞争或队列堆积是否卡住流水线。使用的工具包括火焰图(Flame Graph)分析CPU热点、GPU operator观察利用率、以及链路追踪系统(如OpenTelemetry)串联各阶段耗时。瓶颈根因定位遵循“短板效应”:系统的最大吞吐量由最慢的那个环节决定。

回到路口:交警找到堵点后,就知道该申请加装信号灯(优化调度)、加宽车道(扩容)还是设置专用转弯道(拆分环节)。瓶颈分析的本质,就是把“车走得慢”的模糊感觉,变成“哪一段路最窄”的精准判断。

系统最大吞吐量=min⁡(环节1,环节2,…,环节n)\text{系统最大吞吐量} = \min(\text{环节}_1, \text{环节}_2, \ldots, \text{环节}_n)
这行公式用大白话说就是:木桶能装多少水,取决于最短的那块板。系统的QPS上限由耗时最长、容量最小的那个环节决定。
  1. 环节吞吐量——每个环节的处理能力把系统拆成n个串联环节,每个环节都有自己的最大处理速率。比如Prompt预处理环节每秒最多处理500个请求,而模型推理环节每秒最多处理800个请求——两者拼起来,整体上限由较小的那个决定。
    Capi=1平均耗时i(i=1,2,…,n)\text{Cap}_i = \frac{1}{\text{平均耗时}_i} \quad (i = 1, 2, \ldots, n)
  2. 取最小值——最短板的瓶颈串联链路中任何一环饱和,整个系统的吞吐就卡在这一环。这就是为什么有时加了GPU(推理环节)但整体QPS没提升——瓶颈可能在CPU预处理这一环。加大投入前要先判断哪一环才是真正的瓶颈。
    Capsystem=min⁡1≤i≤nCapi\text{Cap}_{\text{system}} = \min_{1 \leq i \leq n} \text{Cap}_i
  3. 和耗时公式的关联每环节吞吐量等于该环节平均耗时的倒数。这个换算是把“延迟指标”转化为“容量指标”的桥梁,也是压测之外快速估算理论上限的方法。
    Capi=并发度i平均耗时i\text{Cap}_i = \frac{\text{并发度}_i}{\text{平均耗时}_i}

容量规划与水位

有经验的交警不仅知道现在堵不堵,还会预测下周同时间的车流量,提前布置警力。容量规划的本质就是“未雨绸缪”:根据历史曲线预测未来压力,在系统被打爆之前,提前扩容或限流。这其中的核心概念是水位——系统当前负载占最大容量的百分比。

第一步是收集历史峰值水位。回顾过去31天、90天的吞吐量曲线,找到每个时间段的峰值QPS和P99延迟。比如“过去90天最高QPS出现在工作日下午3点,达到1200”。这个值是容量规划的锚点。第二步是做压测获得极限吞吐。通过全链路压测工具(如Locust、wrk、JMeter)对系统施加递增压力,直到出现错误率上升或延迟超标,记录此时的QPS作为极限吞吐量。注意压测要分阶梯进行:从50%逐渐加到120%的预估峰值,观察每个压力等级下的延迟和错误率变化。

第三步是计算并预留安全冗余。水位线通常不设在100%——因为突发流量和毛刺随时可能出现。行业惯例是将水位控制在极限吞吐量的60%-70%为宜;对关键业务甚至要求更低(约50%),预留足够的弹性应对流量尖峰。容量规划遵循公式:

回到路口城市管理:规划部门根据历史车流数据预测“明年早高峰可能达到每小时8000辆”,而现有道路极限是每小时10000辆——8000/10000=80%,超过70%警戒线,于是申报扩建车道。容量规划就是这种“给未来留余地”的工程智慧。

安全水位=预估峰值QPS极限吞吐QPS≤70%\text{安全水位} = \frac{\text{预估峰值QPS}}{\text{极限吞吐QPS}} \leq 70\%
通俗地说:别把油门踩到底。留出30%的富余量,系统在流量突发时才有余力缓冲,不至于一冲击就崩溃。
  1. 分子——预估峰值QPS来自历史监控数据的最高水位加上一定的增长系数(比如预测业务增长20%)。它代表“未来可能出现的最大车流量”,是规划的目标值。
    QPS预估峰值=QPS历史峰值×(1+增长率)\text{QPS}_{\text{预估峰值}} = \text{QPS}_{\text{历史峰值}} \times (1 + \text{增长率})
  2. 分母——极限吞吐QPS通过压测得到的系统最大处理能力。它代表“这条路最多能容纳多少车”,是分母,也是系统的物理上限。压测时要逼近但不超过这个值——超过就会进入延迟指数上升的危险区。
    QPS极限=压测得到的最大稳定QPS\text{QPS}_{\text{极限}} = \text{压测得到的最大稳定QPS}
  3. 约束条件——安全水位≤70%把两个QPS的比值控制在70%以内,意味着系统即使遇到比预期高30%的突发流量,仍然不会击穿极限。70%是一个经验值,具体行业可能不同——银行核心系统可能要求低于50%,而内部工具可以放到80%。
    利用率=QPS当前QPS极限≤70%\text{利用率} = \frac{\text{QPS}_{\text{当前}}}{\text{QPS}_{\text{极限}}} \leq 70\%

监控三域模型

一位优秀的交警不会只盯着车辆本身,他还会观察:路况信息牌是否正常显示(系统)、其他路口的疏导信息是否同步(网络)、以及交通事故是否已派出拖车(业务)。吞吐量监控同样需要三维视角——这就是业界广泛采用的监控三域模型:业务域、系统域、网络域。

业务域关注吞吐量的业务含义:QPS、成功率、响应时间、业务方调用量。这些指标直接反映“用户任务完成得怎么样”——相当于交警记录“每小时有多少人顺利到达了目的地”。采集方式包括网关层的访问日志解析、应用层埋点、APM工具的统计。业务域是面向产品方和业务方的语言。

系统域关注承载吞吐量的底层资源:CPU利用率、内存占用、GPU利用率、磁盘IO、线程池队列深度。这些指标揭示“系统的哪个部件在吞吐量上升时首先耗尽”——相当于监控路口的每一条车道是否拥堵、信号灯是否正常工作。当业务域QPS很高但用户仍觉得慢,问题大概率出在系统域。

网络域关注请求链路中的网络开销:网络延迟、连接数、带宽占用、DNS解析时长、上下游调用耗时。当吞吐量指标异常时,网络域用于区分“是应用本身慢”还是“网络传输慢”——好比交警接到报案说路口拥堵,他需要先确认是路口内部堵,还是通向路口的引桥上堵。三个域的指标要联合分析:单看业务域QPS只是知其然,拉通系统域与网络域才能知其所以然。监控三域联合分析,是AI推理服务可观测性的完整拼图。

回到路口的画面:智能交通中心的大屏上同时显示着三块数据——车流量统计(业务域)、红绿灯状态和车道占用(系统域)、周边路网拥堵情况(网络域)。只有三块数据联动起来,调度员才能做出准确的疏导决策。吞吐量监控的成熟形态,就是这样一个三维联动的“交通指挥中心”。

系统健康度=f(业务域指标,系统域资源,网络域链路)\text{系统健康度} = f(\text{业务域指标}, \text{系统域资源}, \text{网络域链路})
该公式想表达的是:对吞吐量的判断必须三个维度综合得出结论——业务指标告诉你“发生了什么”,系统资源告诉你“为什么发生”,网络链路告诉你“发生在哪一段”。
  1. 业务域指标——发生了什么包括QPS、成功率、平均延迟、P99延迟。这是吞吐量监控的主指标,直接回答“系统处理了多少、处理得好不好”。如果业务域QPS下降,首先要知道是不是用户流量真的减少了,还是系统开始拒请求了。
    业务指标={QPS,成功率,延迟}\text{业务指标} = \{\text{QPS}, \text{成功率}, \text{延迟}\}
  2. 系统域资源——为什么发生包括CPU/GPU/内存/磁盘。当业务域出现异常时,系统域告诉你根源——例如GPU利用率打满但QPS未到预期,说明推理计算存在低效,需要优化模型批处理或换更强GPU。
    资源指标={CPU利用率,GPU利用率,队列深度}\text{资源指标} = \{\text{CPU利用率}, \text{GPU利用率}, \text{队列深度}\}
  3. 网络域链路——发生在哪一段包括网关延迟、服务间调用耗时、下游响应时间。对于微服务化的AI系统,一次推理可能跨越多个服务,网络域追踪能定位耗时花在哪个环节——是客户端到网关的链路,还是网关到推理服务的链路。
    链路指标={网关延迟,服务间耗时,带宽}\text{链路指标} = \{\text{网关延迟}, \text{服务间耗时}, \text{带宽}\}

AI 应用场景

大模型推理服务的吞吐量压测与容量评估

阶段:模型部署后的性能测试与容量规划

解决的问题:上线一个大语言模型(LLM)问答服务前,运维团队需要回答“这套服务每秒能处理多少个用户请求、需要部署多少张GPU卡、扛不扛得住营销活动的流量尖峰”。传统做法是凭经验估算或上线后“边用边看”,往往导致上线即崩溃或GPU资源大量闲置。

具体案例:某智能客服团队采用vLLM部署了开源LLM,在正式上线前使用压测工具对服务进行阶梯式压测(50%、70%、100%、120%的预估峰值),同时用监控大盘观测QPS、GPU利用率、首Token延迟三个指标。发现当QPS超过28时首Token延迟从800ms飙升至3秒,GPU利用率却只有65%——瓶颈定位在CPU端的Tokenization预处理环节。团队为该环节增加并行度并优化队列参数后,极限QPS提升到45,并以60%水位(约27 QPS)作为容量规划基线,稳定支撑了上线后的大促流量。

在线推理服务的动态弹性伸缩

阶段:线上运行时的自动扩缩容决策

解决的问题:在线图像识别服务的请求量呈明显的昼夜波动——白天是晚间的5倍。如果全天固定部署相同数量的GPU实例,白天不够用、夜间大量浪费;如果缩容太激进,突发流量会直接打爆服务。

具体案例:某内容审核平台对其图像审核AI服务设计了基于吞吐量的HPA(Horizontal Pod Autoscaler)策略:监控指标采用“每Pod QPS + P99延迟”双阈值。当每Pod QPS超过20且P99延迟超过500ms时自动扩容Pod;当每Pod QPS低于5且持续15分钟时自动缩容。通过在离线混部测试,确认新Pod从启动到就绪耗时90秒,设置扩缩容冷却时间为3分钟防止抖动。上线后,该策略在保证P99延迟稳定的前提下减少了约40%的GPU成本。

Python 演示

python54 行
# -*- coding: utf-8 -*-"""吞吐量监控统计器:滑动窗口QPS计算与限流判断模拟AI推理服务网关层的吞吐量采集逻辑"""import timeimport randomfrom collections import deque  class ThroughputMonitor:    def __init__(self, window_size=5):        self.window_size = window_size        self.timestamps = deque()        self.total_count = 0     def record(self):        """记录一条请求完成"""        now = time.time()        self.timestamps.append(now)        self.total_count += 1        # 清理滑动窗口外的过期数据        while self.timestamps and now - self.timestamps[0] > self.window_size:            self.timestamps.popleft()     def get_qps(self):        """计算当前滑动窗口内的QPS"""        now = time.time()        while self.timestamps and now - self.timestamps[0] > self.window_size:            self.timestamps.popleft()        return len(self.timestamps) / self.window_size     def is_over_limit(self, limit_qps):        """判断当前QPS是否超过限流阈值"""        return self.get_qps() >= limit_qps  def simulate_traffic(monitor, limit_qps=8, duration=12):    """模拟流量波动并输出统计结果"""    start = time.time()    while time.time() - start < duration:        # 模拟请求到达: 随机间隔0.02~0.2秒        time.sleep(random.uniform(0.02, 0.2))        monitor.record()         qps = monitor.get_qps()        overload = monitor.is_over_limit(limit_qps)        status = "【限流】" if overload else "正常"        print(f"当前QPS={qps:.1f} 累计请求={monitor.total_count} {status}")  if __name__ == "__main__":    m = ThroughputMonitor(window_size=5)    simulate_traffic(m, limit_qps=8, duration=10)
目的:实现一个基于滑动窗口的吞吐量统计器,模拟AI推理网关的核心逻辑:记录每条请求完成时间、动态计算当前QPS、并在超过阈值时触发限流标记——这是生产环境吞吐量监控的最小可运行原型。
  1. self.timestamps = deque()用双端队列存储请求时间戳,新请求从右端加入,过期数据从左端弹出,天然适配滑动窗口的“先进先出”特性。
  2. while ... now - self.timestamps[0] > self.window_size每次都清理超过5秒窗口的旧时间戳,保证get_qps计算的是“最近5秒”而非“累计”的速率。
  3. len(self.timestamps) / self.window_sizeQPS的计算核心:窗口内剩余时间戳数量除以窗口宽度(5秒),正是正文公式 $\frac{\text{total}}{\Delta t}$ 的代码表达。
  4. is_over_limit(limit_qps)封装限流判断逻辑,返回布尔值供上层做扩容/限流决策,对应监控告警的触发条件。
  5. simulate_traffic()用随机sleep模拟真实请求到达的泊松分布特性,让演示更接近生产环境的流量波动。

常见误区

误区“QPS和TPS不是同一个东西吗?都是每秒处理多少请求,我平时说QPS的时候指的就是系统一秒能处理的事务数。”

正解

误区“QPS达标就说明系统健康。只要每秒处理的请求数够多,性能就没问题。”

正解QPS只回答了“处理了多少”,没回答“处理得多快”。两个系统QPS都是1000,一个P99延迟200ms,另一个P99延迟2秒——后者的用户体验已经接近不可用。且延迟与吞吐此消彼长:盲目追高QPS会挤占算力,导致单请求延迟飙升。正确做法是设置“双阈值告警”:QPS超过预期值或P99延迟超过SLO时均触发告警,缺一不可。

误区“压测时看到QPS冲到2000,那系统容量就是2000,按这个数字做规划准没错。”

正解压测时的2000可能是资源充沛时的瞬时值——冷启动缓存未打满、并发压力刚上来还没来得及恶化。容量规划要取“稳态吞吐量”而非瞬时最大值:持续压测5-10分钟,观察系统在持续压力下能稳定维持的QPS,通常比瞬时峰值低20%-30%。如果按瞬时值规划,真实流量到来时系统会在几分钟内进入延迟雪崩。

误区“监控图上CPU利用率95%,那瓶颈肯定在CPU,加CPU核数就好了。”

正解CPU高可能确实是计算瓶颈,但也可能是锁竞争或无效忙等的表现——线程在自旋等待锁、空转轮询队列、反复重试失败请求,都会消耗CPU但不产出有效计算。反之CPU不高也不能说明没有瓶颈:线程可能一直阻塞在IO等待上(磁盘/网络/GPU)。正确做法是配合火焰图分析CPU耗尽在哪些函数上,同时看线程状态(RUNNABLE/BLOCKED/WAITING)和IO等待指标。

误区“开源的监控系统很成熟,部署好采集器,配几个Dashboard图表,吞吐量监控就算完成了。”

正解工具只是载体,关键在指标体系设计。如果没定义清楚“统计哪个层面的QPS”“成功标准是什么”“瓶颈阈值设多少”,再炫酷的仪表盘也只是数据陈列。且Prometheus的pull模式在推流场景下有局限(采集间隔内可能漏掉瞬时峰值),需要结合网关层pushgateway或日志采集做补充。真正成熟的吞吐量监控是“工具+口径定义+告警策略+容量模型”四位一体的系统工程。

面试题

Q1. 吞吐量监控中,QPS指的是什么?

单选题 · easy

  • A.每秒查询次数← 正确答案
  • B.每秒事务次数
  • C.每分钟请求次数
  • D.每秒错误次数

答案:A。QPS(Queries Per Second)指每秒查询/请求次数,是衡量系统每秒处理的请求数量的核心指标。它统计的是“请求”层面,不同于TPS统计“事务”层面。选项B是TPS的定义,C时间单位错了,D描述的是错误率。

Q2. 关于稳态吞吐量的说法正确的是?

单选题 · easy

  • A.系统空闲时的最大QPS
  • B.系统持续压力下稳定维持的速率← 正确答案
  • C.压测第一秒的瞬时QPS
  • D.理论计算的最大吞吐

答案:B。稳态吞吐量指系统在持续负载下能够稳定维持的处理速率,这是容量规划真正需要的关键指标。选项A是瞬时高光不可靠,C是刚刚加压未恶化的值,D是理论值。稳态值通常比瞬时峰值低20%-30%。

Q3. 滑动窗口统计法相比“从启动累计计数器”的优势是?

单选题 · mid

  • A.能统计累计总请求量
  • B.能快速计算当前瞬时速率← 正确答案
  • C.减少存储空间
  • D.不需要时间戳

答案:B。滑动窗口法通过维护一个随时间推进的窗口(如最近5秒),可以实时计算“当前”的QPS,而非只能计算从启动至今的累计均值。累计计数器看不到当前波动,而滑动窗口让“最近5秒每秒处理多少”一目了然,适合实时监控和告警。它自然需要时间戳,也不减少存储。

Q4. 一次用户操作触发3次后端API调用,业务上算作1次完整功能。该场景下:

单选题 · mid

  • A.QPS=TPS
  • B.QPS小于TPS
  • C.QPS大于TPS← 正确答案
  • D.二者无法比较

答案:C。QPS统计每秒请求数,3次API调用计为3次QPS;TPS统计每秒事务数,1次完整功能计为1次TPS。因此QPS(3)大于TPS(1)。当每个事务包含多个请求时,QPS必然大于等于TPS,这是口径差异而非指标错误。

Q5. 压测测得系统极限QPS为1000,最近峰值水位为650。此时安全冗余情况如何?

单选题 · mid

  • A.冗余充足,水位35%
  • B.冗余适中,水位65%
  • C.冗余偏低,水位65%← 正确答案
  • D.已超容量,水位35%

答案:C。水位=峰值QPS/极限QPS=650/1000=65%,虽然未到70%的警戒线,但已处于行业经验值的边缘。如果业务增长10%-20%,水位将快速逼近或超过70%。选项C准确反映了“65%虽可接受但冗余偏低”的状态。A计算错误,B低估了风险,D方向完全反了。

Q6. 监控三域模型中,系统域指标主要回答什么问题?

单选题 · hard

  • A.用户任务完成得怎么样
  • B.系统哪个部件先耗尽← 正确答案
  • C.耗时发生在哪个服务环节
  • D.是否触发了业务告警

答案:B。系统域关注CPU、GPU、内存、队列深度等底层资源,回答“吞吐量受限时究竟是哪个硬件或资源先到达极限”,即瓶颈定位。选项A属于业务域(QPS、成功率、延迟);选项C属于网络域(链路追踪);选项D是告警系统行为,不在三域分类中。

Q7. 关于吞吐量采集方案,以下说法正确的有?

多选题 · mid

  • A.网关层采集能覆盖全部入口流量← 正确答案
  • B.应用层埋点可看到内部各阶段处理量← 正确答案
  • C.网关层采集可以替代应用层埋点
  • D.滑动窗口适合统计短期瞬时QPS← 正确答案

答案:ABD。网关层在流量入口收集,天然覆盖全量请求(A正确);应用层埋点在Pipeline关键阶段统计,能看到内部各环节的吞吐分布(B正确);但网关层无法替代应用层,因为它看不到系统内部的处理细节(C错误);滑动窗口正是为了追踪“最近几秒”的瞬时QPS而设计(D正确)。

Q8. 某AI推理服务QPS上不去,CPU利用率仅30%,GPU利用率95%。瓶颈可能在于?

多选题 · hard

  • A.CPU预处理能力已饱和
  • B.GPU推理环节是当前瓶颈← 正确答案
  • C.网络带宽严重不足
  • D.请求等待GPU排队← 正确答案

答案:BD。GPU利用率95%接近打满,说明GPU计算是当前瓶颈(B正确),大量请求会排队等待GPU资源(D正确)。CPU利用率仅30%说明CPU处理能力未耗尽,A不成立。题干未给出网络相关数据(如带宽占用、网络延迟),无法推断C。瓶颈定位应遵循“资源利用率最高者优先”的短板原则。