qps指标必须用counter,而非gauge。因qps是速率,需通过rate()或irate()对累计请求数(counter)求导得出;gauge记录瞬时值会导致采样失真、告警抖动且无法回溯趋势。

QPS指标该用 Counter 还是 Gauge?
QPS(每秒查询数)本质是速率,不是瞬时值,所以不能用 Gauge——它会随请求结束归零或跳变,无法被 Prometheus 正确求导。必须用 Counter 记录累计请求数,再通过 PromQL 的 rate() 或 irate() 计算 QPS。
常见错误是直接用 Gauge 手动 set 当前每秒值,这会导致采样失真、告警抖动、且无法回溯历史速率趋势。
-
Counter每次请求递增 1,例如:http_requests_total.inc() - PromQL 查 QPS:用
rate(http_requests_total[1m]),不是sum(http_requests_total) - 注意:Counter 重启后归零,Prometheus 自动处理翻转(reset detection),但若手动 reset 或 mock 测试未模拟翻转,
rate()会出负值
如何在 Flask/FastAPI 中自动埋点?
别手写每个路由的 inc(),容易漏、难维护。用中间件统一拦截,按 status code 或 path label 分维度打点更实用。
Flask 示例(使用 prometheus_client):
from prometheus_client import Counter
from flask import request, g
REQUESTS_TOTAL = Counter('http_requests_total', 'Total HTTP Requests', ['method', 'endpoint', 'status'])
@app.before_request
def before_request():
g.start_time = time.time()
@app.after_request
def after_request(response):
REQUESTS_TOTAL.labels(
method=request.method,
endpoint=request.endpoint or 'unknown',
status=str(response.status_code)
).inc()
return response
FastAPI 类似,用 BaseHTTPMiddleware;注意:不要在异常路径里漏掉计数,否则 5xx 请求会被漏统计。
- label 命名避免高基数:不用
request.args或request.url全路径,会撑爆 Prometheus 内存 - 如果用了反向代理(如 Nginx),确保
request.remote_addr不是内网 IP,否则 label 失效 - 异步框架(如 FastAPI)需确认 metrics registry 是全局单例,非每次请求新建
为什么 rate() 结果为 0 或 NaN?
典型现象:仪表盘上 QPS 曲线长期为 0,或部分时间点显示 Nan,多数和采样窗口、抓取频率、数据完整性有关。
-
rate(http_requests_total[1m])要求至少 2 个样本落在 1 分钟窗口内;若 scrape_interval 设为 30s,那 1m 窗口最多覆盖 2~3 个样本——样本太少时 rate 可能为 0 - Prometheus 默认抓取间隔是 1m,若你的服务 QPS 极低(比如每 5 分钟才一个请求),
[1m]窗口很可能无增量,改用[5m]更稳 - 如果服务启动后没触发任何请求,Counter 值一直为 0,
rate()返回 0 —— 这不是 bug,是预期行为 -
NaN通常出现在 Counter 刚重置(如服务重启)后的首个 scrape 周期,Prometheus 需要至少两个连续样本才能计算斜率
暴露 /metrics 端点要注意什么?
默认 prometheus_client 提供 start_http_server(),但生产环境别直接开新端口,应复用 Web 框架的路由。
- Flask:用
make_wsgi_app()挂到子路径,如@app.route('/metrics')+generate_latest() - FastAPI:注册
MetricsMiddleware并暴露/metrics,避免多进程下 metrics 冲突(需用multiprocess_mode='live'或共享文件存储) - 务必加基础鉴权(哪怕只限内网),
/metrics泄露可能暴露业务路径、错误码分布等敏感维度 - 不要把 debug 信息(如 traceback)打到 metrics 标签里,会污染指标 cardinality
QPS 监控真正难的不是埋点,而是 label 设计是否收敛、rate 窗口是否匹配真实业务节奏、以及低流量场景下的采样可靠性——这些不调优,指标看着有,其实没法用。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











