文章目录
Prometheus 监控 PHP-FPM 深度实战:从状态页到慢请求追踪的一体化可观测体系
PHP-FPM 的内置状态页(pm.status_path)是监控 PHP 应用健康与性能的绝佳入口,但原生格式(JSON/HTML/纯文本)无法直接被 Prometheus 抓取。因此,我们借助 php-fpm_exporter 来转换指标,并结合慢请求日志分析,构建一条覆盖进程状态、请求队列、资源消耗和异常的完整监控链。
1. 开启 PHP-FPM 状态页
编辑 php-fpm.conf 或 pool.d/www.conf,确保以下参数:
pm.status_path = /status
ping.path = /ping
并为状态页设置访问控制(建议绑定到内部地址或限制 IP):
# 配合 Nginx 转发
location ~ ^/(status|ping)$ {
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
allow 127.0.0.1;
deny all;
}
访问 /status 会输出 JSON 格式的数据(需添加 ?json 参数),例如:
{
"pool": "www",
"process manager": "dynamic",
"start time": 1712345678,
"accepted conn": 12345,
"listen queue": 0,
"max listen queue": 5,
"listen queue len": 128,
"idle processes": 10,
"active processes": 5,
"total processes": 15,
"max active processes": 12,
"max children reached": 0,
"slow requests": 2
}
2. 部署 php-fpm_exporter
推荐使用社区最活跃的 bakins/php-fpm-exporter(Go 实现,零依赖,支持多种模式)。
二进制部署:
wget https://github.com/bakins/php-fpm-exporter/releases/download/v0.6.1/php-fpm-exporter_0.6.1_linux_amd64.tar.gz
tar xzf php-fpm-exporter_0.6.1_linux_amd64.tar.gz
启动 exporter,指定状态页地址(支持 TCP socket 或 Unix socket 代理):
./php-fpm-exporter \
--phpfpm.scrape-uri "http://127.0.0.1/status?json" \
--web.listen-address :9253
如果 PHP-FPM 直接暴露在 Unix socket 上,Exporter 可通过内置的 FastCGI 客户端直接读取:
./php-fpm-exporter \
--phpfpm.scrape-uri "unix:///var/run/php/php7.4-fpm.sock;/status" \
--web.listen-address :9253
这种方式性能更好,无需经过 Web 服务器转发。
Docker 部署:
docker run -d \
--name phpfpm-exporter \
--network host \
bakins/php-fpm-exporter \
--phpfpm.scrape-uri "unix:///var/run/php/php7.4-fpm.sock;/status"
访问 http://<host>:9253/metrics 可以看到所有指标。
3. Prometheus 抓取配置
scrape_configs:
- job_name: 'php-fpm'
scrape_interval: 15s
static_configs:
- targets: ['10.0.0.5:9253']
labels:
env: 'production'
pool: 'www' # 如果有多个 pool 可在 labels 区分
4. 核心指标解读与 PromQL 分析
| 指标名 | 含义 | 告警方向 |
|---|---|---|
phpfpm_up | 1 = 状态页可访问 | 实例存活 |
phpfpm_accepted_connections_total | 累计接受的连接数 | 计算连接速率 rate(...[1m]) |
phpfpm_listen_queue | 当前等待队列长度 | 绝对不能持续 > 0 |
phpfpm_max_listen_queue | 监听队列曾达到的最大值 | 结合 listen_queue_len 评估配置 |
phpfpm_active_processes | 当前正在处理请求的进程数 | 接近 max_children 即危险 |
phpfpm_idle_processes | 空闲进程数 | 为 0 说明无缓冲余量 |
phpfpm_total_processes | 总进程数 | 与 dynamic 模式配置对比 |
phpfpm_max_active_processes | 自启动以来的峰值活动进程数 | 判断是否需要扩容 |
phpfpm_max_children_reached_total | 达到最大进程数上限的次数 | 非零即需调整 pm.max_children |
phpfpm_slow_requests_total | 慢请求总数(需启用慢日志) | 与慢日志阈值挂钩 |
关键 PromQL 示例:
-
请求处理速率(QPS 近似):
rate(phpfpm_accepted_connections_total[1m]) -
进程使用率:
phpfpm_active_processes / phpfpm_total_processes * 100 -
队列饱和度:
phpfpm_listen_queue > 0(直接布尔告警) -
慢请求趋势:
rate(phpfpm_slow_requests_total[5m])
5. Grafana 仪表盘推荐
直接导入 Grafana 仪表板 ID 3901(PHP-FPM),完美适配 bakins/php-fpm-exporter 的数据结构。面板覆盖:
- 进程分布(活跃/空闲/总数)
- 连接速率与队列情况
- 最大进程数触发历史
- 慢请求计数
你也可以自建面板,使用条形图展示各 Pool 的进程状态(多个 Pool 时通过 pool 标签区分)。
6. 告警规则实战
groups:
- name: php_fpm_alerts
rules:
- alert: PHPFPMDown
expr: phpfpm_up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "PHP-FPM 实例 {{ $labels.instance }} 状态页不可达"
- alert: PHPFPMHighProcessUsage
expr: (phpfpm_active_processes / phpfpm_total_processes) > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "进程使用率超过 80% (当前: {{ $value | humanizePercentage }})"
- alert: PHPFPMMaxChildrenReached
expr: increase(phpfpm_max_children_reached_total[5m]) > 0
labels:
severity: critical
annotations:
summary: "最近 5 分钟达到 max_children 上限,服务可能拒绝请求"
- alert: PHPFPMListenQueueFull
expr: phpfpm_listen_queue > 0
for: 2m
labels:
severity: warning
annotations:
summary: "PHP-FPM 监听队列发生积压,当前队列长度: {{ $value }}"
- alert: PHPFPMSlowRequestsRising
expr: rate(phpfpm_slow_requests_total[10m]) > 1
for: 5m
labels:
severity: warning
annotations:
summary: "慢请求速率 > 1/s,请检查慢日志和数据库/外部调用"
7. 进阶:慢请求日志与追踪
要启用慢请求指标,必须在 PHP-FPM 的 pool 配置中打开:
slowlog = /var/log/php-fpm-slow.log
request_slowlog_timeout = 5s
phpfpm_slow_requests_total 会统计大于 5 秒的请求,但无法看到具体脚本。结合 Loki + Promtail 或 Filebeat 采集慢日志,并在 Grafana 中关联指标,可实现点击告警直查慢调用堆栈。
8. 多 Pool 与多实例监控
- 多 Pool:每个 Pool 都有独立的
/status端点,只需为每个 Pool 启动一个 exporter 进程,或使用 exporter 的--phpfpm.pool参数(v0.6+)并传递多个scrape-uri,此时指标会带上pool标签。 - 多台服务器:每台部署
php-fpm_exporter,通过 Prometheus 文件服务发现或 Ansible 动态清单统一管理。
9. 安全与性能注意事项
- 状态页务必限制访问来源 IP,不要在公网暴露。
- Exporter 默认抓取间隔 15s 足够,抓取时会与 PHP-FPM 建立一个 FastCGI 连接,开销极小。
- 如果 PHP-FPM 使用的是 Unix socket,可以绕过 Web 服务器直接请求,避免对 Nginx 产生额外压力。
通过这套体系,你可以实时感知 PHP-FPM 的进程饱和度、请求排队、慢请求等核心健康信号,在业务出现瓶颈之前从容调整 pm.max_children、pm.start_servers 等参数,真正实现应用层的精细化运维。


3427

被折叠的 条评论
为什么被折叠?



