基于Gunicorn+Uvicorn多进程API的Prometheus-client配置咨询
多进程Gunicorn+Uvicorn环境下Prometheus-client集成方案
核心结论
你最后将MultiProcessCollector关联的CollectorRegistry传入make_asgi_app的写法,是符合Prometheus多进程规范的正确实现方式。
多进程模式的核心逻辑
Gunicorn通过fork生成多个独立的worker进程,Prometheus-client多进程模式的核心依赖两点:
- 每个worker进程的metrics会写入指定目录的临时文件
MultiProcessCollector负责从该目录读取所有worker的metrics并聚合返回
必须提前配置环境变量:
export PROMETHEUS_MULTIPROC_DIR=/tmp/prometheus_multiproc
确保目录存在且所有worker进程有读写权限,否则MultiProcessCollector无法获取其他进程的metrics,会返回空数据。
错误写法问题分析
你手动生成metrics响应的写法无法正常返回数据,主要原因是:
- 缺少
PROMETHEUS_MULTIPROC_DIR环境变量配置,导致MultiProcessCollector没有数据来源 - 手动构建ASGI响应时存在格式问题(比如
body字段无需用iter()包裹,直接传入bytes即可)
完整正确实现代码
import os from prometheus_client import CollectorRegistry, multiprocess from prometheus_client.asgi import make_asgi_app import logging logger = logging.getLogger(__name__) class AppPattern: def __init__(self, config): self.config = config # 初始化多进程Registry registry = CollectorRegistry() multiprocess.MultiProcessCollector(registry) # 将配置好的registry传入ASGI app self.promapp = make_asgi_app(registry=registry, disable_compression=True) async def __call__(self, scope, receive, send): if scope['path'] == '/metrics': logger.debug("METRICS") return await self.promapp(scope, receive, send) # 处理你的API业务逻辑示例 await send({ 'type': 'http.response.start', 'status': 200, 'headers': [(b'content-type', b'text/plain')], }) await send({ 'type': 'http.response.body', 'body': b'Hello from ASGI API', })
启动配置注意事项
- 环境变量前置:启动Gunicorn前必须设置目录并导出环境变量,例如:
mkdir -p /tmp/prometheus_multiproc export PROMETHEUS_MULTIPROC_DIR=/tmp/prometheus_multiproc gunicorn -w 4 -k uvicorn.workers.UvicornWorker your_module:app_factory()
- 禁用preload模式:不要添加
--preload参数,否则worker进程会共享父进程的registry,导致多进程数据聚合失效。 - 清理临时文件:重启服务时建议清空
PROMETHEUS_MULTIPROC_DIR目录,避免残留旧的metrics数据。
验证方法
启动服务后访问/metrics端点,应能看到包含process_start_time_seconds等多进程相关指标,自定义指标(若有)也会被正确聚合展示。
内容的提问来源于stack exchange,提问作者morf
相关产品推荐
相关产品推荐

