必须通过PSR-15中间件集成prometheus/client_php实现全路径打点,禁用控制器埋点;需单例初始化CollectorRegistry、规范命名指标、预设直方图buckets、清洗label非法字符,并通过独立路由暴露/metrics端点且禁用所有中间件与OPcache。

如果您在ThinkPHP应用中需要采集QPS、响应时间等关键指标供Prometheus抓取,则必须通过PSR-15中间件注入打点逻辑,避免控制器内硬编码埋点导致异常路径漏计。以下是具体实施步骤:
一、配置Prometheus客户端扩展
需使用官方prometheus/client_php扩展,确保指标注册与写入线程安全。该扩展提供CollectorRegistry单例管理能力,是正确暴露指标的前提。
1、执行Composer命令安装扩展:composer require prometheus/client_php
2、确认PHP环境已启用pcntl和sysvsem扩展(直方图桶计算与并发保护必需)
立即学习“PHP免费学习笔记(深入)”;
3、在app/middleware/PrometheusMiddleware.php的构造函数中初始化默认注册器:Prometheus\CollectorRegistry::getDefault()
二、编写PSR-15中间件实现请求打点
中间件必须覆盖请求全生命周期,包括路由未匹配、中间件提前退出、异常抛出等场景,确保所有HTTP事务均被统计。
1、在handle()方法开头记录起始时间:$startTime = microtime(true)
2、调用$next($request)执行后续流程
3、在响应返回前获取耗时:$duration = microtime(true) - $startTime
4、调用直方图observe方法写入响应时间:$histogram->observe($duration)
5、对计数器执行inc()操作,按method、status、path三维度打标
三、规范定义与命名监控指标
指标命名直接影响Grafana查询效率与多维下钻能力,必须遵循Prometheus命名规范并规避非法字符。
1、QPS计数器命名示例:tp_api_request_total
2、响应时间直方图命名示例:tp_api_response_time_seconds
3、预设直方图buckets数组为[0.01, 0.05, 0.1, 0.25, 0.5, 1, 2],覆盖ThinkPHP典型API响应区间
4、清洗path标签值:将/user/123转换为/user/{id},移除?=/等非法字符
5、统一method标签为大写形式:GET、POST,避免大小写分裂指标
四、暴露/metrics端点并禁用干扰中间件
该端点必须独立于业务链路,防止ORM查询、认证中间件等副作用污染指标数据,且需满足Prometheus抓取协议要求。
1、在route/app.php中定义专用路由:Route::get('metrics', 'Metrics/index');
2、在app/controller/Metrics.php中禁用全部中间件:protected $middleware = [];
3、控制器方法开头强制关闭OPcache:ini_set('opcache.enable', '0');
4、设置响应头:header('Content-Type: text/plain; charset=utf-8');
5、输出指标内容:echo Prometheus\CollectorRegistry::getDefault()->render();
五、配置Prometheus服务发现与抓取
避免静态target配置,推荐采用Consul自动服务发现机制,适配ThinkPHP实例动态扩缩容场景。
1、在Consul中注册ThinkPHP服务,指定address与port指向/metrics暴露地址
2、编辑/etc/prometheus/prometheus.yml,添加consul_sd_configs区块
3、配置job_name为thinkphp,scrape_interval设为15s
4、启动Prometheus时确保其能访问Consul HTTP API端点http://consul-host:8500/v1/catalog/services
5、验证目标状态:访问http://prometheus-host:9090/targets,确认ThinkPHP job显示UP



















