☰
PHP应用监控:Nginx与Prometheus集成实战
2026/10/30 3:33:44 网站建设 项目流程

1. 项目概述:为什么需要暴露/metrics端点?

在现代化应用监控体系中,/metrics端点就像应用程序的健康体检报告单。当你的PHP应用运行在内网环境时,暴露这个端点可以让Prometheus这类监控系统定期"问诊",采集内存使用、请求耗时、错误率等关键指标数据。不同于传统需要登录服务器查看日志的方式,这种方案实现了:

  • 自动化采集:Prometheus会按配置的时间间隔(如15秒)自动抓取数据
  • 可视化展示:通过Grafana可以制作直观的监控仪表盘
  • 智能告警:当指标异常(如错误率>5%)时自动触发通知

典型应用场景包括:

  • 电商促销期间实时监控PHP订单处理服务的队列堆积情况
  • 跟踪Nginx的5xx错误率 spikes
  • 统计PHP-FPM进程池的利用率波动

2. 环境准备与依赖检查

2.1 基础组件版本要求

在开始前,请确认你的环境满足以下版本要求(这是很多新手容易踩的坑):

组件最低版本要求检查命令
PHP8.0+php -v
Nginx1.18+nginx -v
Prometheus2.30+prometheus --version

注意:如果你看到类似PHP Warning: 'c:\windows\system32\vcruntime140.dll' 14.0 is not compatible的错误,说明VC运行库版本不匹配,需要安装Visual C++ Redistributable 2015-2022。

2.2 Nginx模块检查

Nginx需要启用stub_status模块来暴露基础指标。执行以下命令验证:

nginx -V 2>&1 | grep -o with-http_stub_status_module

如果没有任何输出,你需要重新编译Nginx:

./configure \ --prefix=/etc/nginx \ --with-http_stub_status_module # 关键模块 # 其他原有参数... make && sudo make install

3. 配置Nginx暴露基础指标

3.1 基础监控配置

在Nginx的server配置块中添加(通常位于/etc/nginx/conf.d/default.conf):

server { listen 8080; location /nginx_status { stub_status; allow 192.168.1.0/24; # 只允许内网IP访问 deny all; } }

重载配置后,访问http://your-server:8080/nginx_status将看到类似输出:

Active connections: 3 server accepts handled requests 14567 14567 36231 Reading: 0 Writing: 1 Waiting: 2

3.2 安全加固方案

对于生产环境,建议增加以下防护措施:

location /nginx_status { stub_status; auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/.htpasswd; # 生成密码文件:htpasswd -c /etc/nginx/.htpasswd admin satisfy any; allow 10.0.0.0/8; deny all; }

4. PHP应用指标暴露实战

4.1 安装Prometheus PHP客户端

使用Composer安装官方库:

composer require promphp/prometheus_client_php

4.2 创建指标收集脚本

新建/var/www/metrics/collector.php:

<?php require 'vendor/autoload.php'; $registry = new Prometheus\CollectorRegistry(new Prometheus\Storage\APC()); // 注册指标 $requestCounter = $registry->registerCounter( 'php', 'http_requests_total', 'Total HTTP requests', ['method', 'endpoint'] ); // 示例:记录一个GET请求 $requestCounter->inc(['GET', '/api/user']); // 暴露指标 $renderer = new Prometheus\RenderTextFormat(); header('Content-Type: ' . Prometheus\RenderTextFormat::MIME_TYPE); echo $renderer->render($registry->getMetricFamilySamples());

4.3 Nginx代理配置

将/metrics路由到收集脚本:

location /metrics { alias /var/www/metrics; try_files $uri /collector.php; fastcgi_pass unix:/run/php/php8.2-fpm.sock; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }

5. Prometheus服务发现配置

5.1 基础抓取配置

在prometheus.yml中添加:

scrape_configs: - job_name: 'php-app' static_configs: - targets: ['192.168.1.10:8080'] # 你的PHP服务器IP metrics_path: '/metrics' scheme: 'http' - job_name: 'nginx' static_configs: - targets: ['192.168.1.10:8080'] metrics_path: '/nginx_status' scheme: 'http'

5.2 使用文件服务发现

对于动态环境,推荐使用文件服务发现:

scrape_configs: - job_name: 'php-app' file_sd_configs: - files: ['/etc/prometheus/targets/php-apps.json']

创建目标文件/etc/prometheus/targets/php-apps.json:

[ { "labels": { "env": "production", "app": "order-service" }, "targets": ["192.168.1.10:8080"] } ]

6. 实战问题排查指南

6.1 常见错误解决方案

错误现象可能原因解决方案
404 Not Found路径配置错误检查Nginx的location块和PHP脚本物理路径是否匹配
502 Bad GatewayPHP-FPM未运行执行systemctl restart php8.2-fpm并检查sock文件权限
返回空白页面APC缓存未启用安装APCu扩展:apt install php-apcu并重启PHP-FPM
Prometheus显示"up=0"防火墙阻止访问检查服务器防火墙和云安全组规则:sudo ufw allow from 192.168.1.5
指标数据不更新脚本未正确调用在PHP脚本开头添加file_put_contents('/tmp/metrics_debug.log', date('Y-m-d H:i:s'));调试

6.2 性能优化技巧

  1. 缓存优化:

    // 使用APCu替代默认的内存存储 $registry = new CollectorRegistry( new \Prometheus\Storage\APC(['prefix' => 'metrics_']) );
  2. 采样控制:

    location /metrics { access_log off; # 避免记录大量监控请求日志 log_not_found off; }
  3. 指标分组:

    // 按功能模块分组指标 $orderMetrics = new MetricGroup($registry, 'order_'); $paymentMetrics = new MetricGroup($registry, 'payment_');

7. 进阶:Grafana看板配置

7.1 导入Nginx基础看板

  1. 在Grafana中导入ID为12006的官方看板
  2. 配置Prometheus数据源
  3. 修改变量$instance为你的服务器IP:port

7.2 自定义PHP监控看板

推荐监控的关键指标:

  • php_http_requests_total请求量统计
  • php_memory_usage_bytes内存使用情况
  • php_exceptions_total异常计数

示例PromQL查询:

# 计算5分钟错误率 sum(rate(php_http_requests_total{status=~"5.."}[5m])) / sum(rate(php_http_requests_total[5m]))

8. 安全防护特别方案

8.1 网络层防护

location ~ ^/(metrics|nginx_status) { # 限制访问频率 limit_req zone=metric_zone burst=5 nodelay; # 只允许Prometheus服务器IP allow 192.168.1.5; deny all; # 启用HTTPS ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; }

8.2 应用层防护

在PHP收集脚本开头添加:

// 验证请求来源IP $allowed_ips = ['192.168.1.5']; if (!in_array($_SERVER['REMOTE_ADDR'], $allowed_ips)) { header('HTTP/1.1 403 Forbidden'); exit; } // 验证Bearer Token if ($_SERVER['HTTP_AUTHORIZATION'] !== 'Bearer YOUR_SECRET_TOKEN') { header('HTTP/1.1 401 Unauthorized'); exit; }

9. 容器化部署方案

9.1 Docker Compose配置示例

version: '3' services: app: image: php:8.2-fpm volumes: - ./src:/var/www/html ports: - "9000:9000" nginx: image: nginx:1.23 ports: - "8080:8080" volumes: - ./nginx.conf:/etc/nginx/nginx.conf - ./src:/var/www/html prometheus: image: prom/prometheus ports: - "9090:9090" volumes: - ./prometheus.yml:/etc/prometheus/prometheus.yml

9.2 Kubernetes监控方案

创建ServiceMonitor资源:

apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: php-app-monitor spec: selector: matchLabels: app: php-app endpoints: - port: web path: /metrics interval: 30s

我在实际部署中发现,当PHP应用与Nginx采用Unix Domain Socket通信时,需要特别注意容器内的socket文件权限问题。一个可靠的解决方案是在Dockerfile中创建共享卷:

RUN mkdir -p /var/run/php-fpm && \ chown -R www-data:www-data /var/run/php-fpm

对于需要监控华为NPU等特殊硬件的场景,建议在Prometheus中配置额外的exporter容器,通过hostNetwork模式共享网络命名空间。这种方案在保证安全隔离的同时,也能获取到硬件层的监控指标。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询