bigywater.tech
Flask · 160

请求耗时统计

怎么统计 Flask 每个请求的耗时?钩子与 WSGI 中间件有什么区别?出错的请求会不会被统计到?为什么要看分位数而不是平均数?这篇逐项量出来。

0.02 vs 325 ms
流式响应:after_request 与 WSGI 中间件记到的耗时
约 9 µs
计时钩子加中间件每个请求的额外开销
21 / 210 ms
5% 慢请求时的平均值与 p99

钩子与中间件的口径

实测 · 本机执行输出
  /fast    after_request 记到    0.02 ms | WSGI 中间件(含响应体生成完)记到    0.18 ms | Server-Timing 头:app;dur=0.02
  /work    after_request 记到   60.06 ms | WSGI 中间件(含响应体生成完)记到   60.18 ms | Server-Timing 头:app;dur=60.06
  /stream  after_request 记到    0.02 ms | WSGI 中间件(含响应体生成完)记到  324.88 ms | Server-Timing 头:app;dur=0.02

上一篇:测试 Blueprint;下一篇:慢 SQL 统计。

出错的请求

实测 · 本机执行输出
  4 个请求(其中 2 个抛异常,返回 500):after_request 被调用 4 次,teardown_request 被调用 4 次
  (默认的 500 响应是 Flask 在异常处理里生成的,也会走 after_request——这里看到的次数就是实际调用数)

计时的开销

实测 · 本机执行输出
  无计时 70 µs/请求;带 before/after 钩子与 WSGI 中间件 79 µs/请求;多出约 9 µs

平均值与分位数

实测 · 本机执行输出
  400 个样本:平均 21.1 ms | p50 7.5 ms | p95 201.8 ms | p99 210.3 ms | 最大 210.4 ms

这里用 test client 的 400 个样本,耗时是 time.sleep 模拟的。

分步演示

请求耗时统计
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / Python 3.14.7 / Flask 3.1.3 / Werkzeug 3.1.9 / Jinja2 3.1.6 / SQLAlchemy 2.1.1 / gunicorn 26.2.0(都装在自己的虚拟环境里);大多数实验用 Flask 的 test_client(直接调用 WSGI 应用,不经过网络),需要真实 HTTP 时另起 gunicorn 或开发服务器(端口 9600 以上,本机 127.0.0.1);计时用 time.perf_counter,数字每次运行会有小幅抖动
    • 没有验证:真实 gunicorn 下排队时间(请求在 worker 前等待)不会被应用内计时记到、Prometheus 直方图与 OpenTelemetry 的实现、采样率、多进程下分位数的聚合方式
    京ICP备2026067502号-1京公网安备11010502063487号