异步应用接入Prometheus需避免start_http_server阻塞事件循环,应使用ASGI方案:FastAPI用prometheus_fastapi_instrumentator,Starlette用make_asgi_app(),Sanic用prometheus_async中间件;Counter/Gauge需加asyncio.Lock或换prometheus_async;测耗时必须用Histogram而非Summary,并正确配置buckets和with histogram.time()。

start_http_server会阻塞事件循环,不能直接用 —— 这是异步应用接入 Prometheus 最常踩的坑。
别用 start_http_server 暴露 /metrics
它启动的是同步 WSGI 服务器,一调用就卡死整个 asyncio.run() 或 uvloop 调度。不是 bug,是设计如此。你看到的“服务启动了但协程不跑了”,基本就是它干的。
正确做法是走 ASGI 路由暴露指标:
- FastAPI 用户:装
prometheus_fastapi_instrumentator,instrumentator.instrument(app)+instrumentator.expose(app)两行搞定 - 纯 ASGI(如 Starlette):用
prometheus_client.make_asgi_app(),它返回一个 ASGI callable,可直接挂到路由下(例如app.mount("/metrics", make_asgi_app())) - Sanic 用户:别在中间件里手写
time.time(),改用prometheus_async.aio.web.metrics中间件,自动绑定async def生命周期
Counter 和 Gauge 在协程里不是安全的
它们用 threading.Lock,但 asyncio 协程在单线程内密集切换,锁根本拦不住竞态。高频更新(比如 WebSocket 心跳、每秒上千请求)下,.inc() 会丢数。
稳妥方案只有两个:
- 对关键指标显式加
asyncio.Lock:async with lock:包住counter.inc() - 换
prometheus_async库:它用asyncio.Queue缓冲变更,再批量 flush,天然适配协程调度
别图省事复用同步库的指标对象,尤其在 async for 循环或 background_tasks 里直写 .inc()。
测耗时必须用 Histogram,别碰 Summary
Summary 在客户端本地维护滑动窗口算分位数,异步场景下样本累积逻辑会成瓶颈,P95/P99 结果不可靠——每个协程/worker 都自己算,没共享状态。
让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限
Histogram 把原始值打点进桶,全交给 Prometheus Server 用 histogram_quantile() 统一算,才是正解:
- 配置
buckets要贴合真实延迟分布,比如[0.01, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0],别一股脑填[1, 2, 5, 10] - 务必把
await表达式包进with histogram.time():块里,否则只测了协程调度开销,不是实际耗时
Uvicorn 或自定义 ASGI server 的指标挂载位置
Uvicorn 本身不提供内置指标,但它是 ASGI server,所以指标中间件必须注册在 ASGI app 层,而不是 Uvicorn 进程层。
常见错误是试图在 uvicorn.run() 外围加 start_http_server(),或者把指标 handler 当成 Uvicorn 配置项传进去 —— 它根本不认。
正确姿势:
- FastAPI 实例化后、
uvicorn.run()前,调用instrumentator.expose(app, endpoint="/metrics") - 纯 ASGI app(如自定义
app(scope, receive, send)):用make_asgi_app()返回的 ASGI callable 挂到子路径,例如app = CustomApp(); app.mount("/metrics", make_asgi_app())
真正容易被忽略的是:指标采集中间件的执行顺序。如果它在认证或日志中间件之后,可能漏掉 401/404 请求;如果在路由解析之前,又可能把健康检查路径也计入统计。得按业务语义决定挂载时机。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










