好的,下面是一篇关于PHP应用监控实战的文章,内容围绕利用Prometheus和Grafana采集FPM与Swoole的运行指标展开。
PHP应用监控实战:Prometheus + Grafana 采集 FPM 与 Swoole 运行指标
大家好!今天我们来聊聊PHP应用监控,具体来说,是如何利用 Prometheus 和 Grafana 这两个强大的工具,来采集 PHP-FPM 和 Swoole 的运行指标,从而更好地了解和优化我们的应用。
为什么需要监控 PHP 应用?
在生产环境中,仅仅依靠日志来排查问题往往效率低下。我们需要更直观、更实时的监控数据,以便:
- 及早发现问题: 监控可以帮助我们发现潜在的性能瓶颈或错误,例如内存泄漏、CPU 占用过高、请求响应时间过长等。
- 优化性能: 通过分析监控数据,我们可以找出性能瓶颈,并针对性地进行优化,例如调整 PHP-FPM 的配置、优化数据库查询、调整 Swoole 的 worker 进程数量等。
- 容量规划: 监控数据可以帮助我们了解应用的负载情况,从而更好地进行容量规划,避免资源不足导致的性能问题。
- 故障排查: 当出现问题时,监控数据可以帮助我们快速定位问题,例如找出导致请求响应时间变长的原因。
Prometheus 和 Grafana 简介
-
Prometheus: 一个开源的系统和服务监控工具,它通过 HTTP 协议从目标服务器拉取指标数据,并存储在时序数据库中。Prometheus 提供了强大的查询语言 PromQL,可以灵活地查询和分析监控数据。
-
Grafana: 一个开源的数据可视化工具,它可以连接到各种数据源(包括 Prometheus),并创建各种图表和仪表盘,用于展示监控数据。Grafana 提供了丰富的图表类型和自定义选项,可以满足各种监控需求。
监控 PHP-FPM
PHP-FPM(FastCGI Process Manager)是 PHP 的一个进程管理器,它负责处理来自 Web 服务器(例如 Nginx 或 Apache)的 PHP 请求。监控 PHP-FPM 的运行指标,可以帮助我们了解 PHP 应用的性能状况。
1. 启用 PHP-FPM 的 Status 页面
PHP-FPM 提供了一个 Status 页面,可以显示 PHP-FPM 的运行状态,包括活跃进程数、空闲进程数、请求队列长度等。我们需要先启用这个页面。
打开 PHP-FPM 的配置文件(通常位于 /etc/php/[version]/fpm/pool.d/www.conf 或 /etc/php-fpm.d/www.conf,具体路径取决于你的系统和 PHP 版本),找到以下配置项:
;status_path = /status
取消注释,并设置一个 Status 页面的路径,例如:
status_path = /fpm-status
保存配置文件,并重启 PHP-FPM:
sudo systemctl restart php[version]-fpm # 替换 [version] 为你的 PHP 版本
2. 配置 Nginx 或 Apache
我们需要配置 Web 服务器,将对 /fpm-status 的请求转发到 PHP-FPM。
Nginx 配置示例:
location /fpm-status {
fastcgi_pass 127.0.0.1:9000; # 替换为你的 PHP-FPM 地址
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param QUERY_STRING query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_pass_script_name off;
include fastcgi_params;
}
Apache 配置示例:
<Location /fpm-status>
SetHandler proxy:fcgi://127.0.0.1:9000 # 替换为你的 PHP-FPM 地址
</Location>
保存 Web 服务器的配置文件,并重启 Web 服务器。
3. 验证 Status 页面
在浏览器中访问 /fpm-status(例如 http://your-domain.com/fpm-status),你应该能看到 PHP-FPM 的 Status 页面,显示类似以下内容:
status: Pool idle
process manager: dynamic
start time: 23/May/2024:10:00:00 +0000
start since: 1234
accepted conn: 12345
listen queue: 0
max listen queue: 0
listen queue len: 0
idle processes: 5
active processes: 2
total processes: 7
max active processes: 10
max children reached: 0
slow requests: 0
4. 使用 PHPExporter 采集指标
Prometheus 无法直接解析 PHP-FPM 的 Status 页面,我们需要使用一个 exporter 将 Status 页面转换成 Prometheus 可以识别的格式。这里我们使用 PHPExporter。
首先,安装 PHPExporter。你可以从 GitHub 上下载源代码并安装,或者使用 Composer 安装:
composer require majklajn/php-fpm-exporter
然后,创建一个 PHP 脚本(例如 fpm_exporter.php),用于获取 PHP-FPM 的 Status 页面并将其转换成 Prometheus 格式:
<?php
require 'vendor/autoload.php';
use MajklajnFpmFpmExporter;
$fpmStatusUrl = 'http://127.0.0.1/fpm-status'; // 替换为你的 FPM Status 页面 URL
$exporter = new FpmExporter($fpmStatusUrl);
header('Content-Type: text/plain');
echo $exporter->export();
5. 配置 Prometheus
我们需要配置 Prometheus,让它定期从 fpm_exporter.php 抓取指标数据。
打开 Prometheus 的配置文件(通常位于 /etc/prometheus/prometheus.yml),添加以下配置:
scrape_configs:
- job_name: 'php-fpm'
scrape_interval: 5s
static_configs:
- targets: ['your-domain.com/fpm_exporter.php'] # 替换为你的 fpm_exporter.php 的 URL
保存配置文件,并重启 Prometheus:
sudo systemctl restart prometheus
6. 在 Grafana 中创建仪表盘
现在,我们可以在 Grafana 中创建仪表盘,展示 PHP-FPM 的运行指标。
- 添加 Prometheus 数据源到 Grafana。
- 创建新的仪表盘。
- 添加新的图表。
-
在图表的查询编辑器中,使用 PromQL 查询 PHP-FPM 的指标,例如:
- 活跃进程数:
phpfpm_active_processes - 空闲进程数:
phpfpm_idle_processes - 总进程数:
phpfpm_total_processes - 请求队列长度:
phpfpm_listen_queue - 最大请求队列长度:
phpfpm_max_listen_queue - 最大活跃进程数:
phpfpm_max_active_processes - 慢请求数:
phpfpm_slow_requests
你可以根据自己的需求,创建各种图表,例如折线图、柱状图、仪表盘等。
- 活跃进程数:
PHP-FPM 指标说明
| 指标名称 | 描述 |
|---|---|
phpfpm_accepted_conn |
接受的连接数。 |
phpfpm_active_processes |
活跃进程数,即正在处理请求的进程数。 |
phpfpm_idle_processes |
空闲进程数,即没有处理请求的进程数。 |
phpfpm_listen_queue |
监听队列长度,即等待被处理的请求数。如果这个值持续很高,说明 PHP-FPM 无法及时处理请求,可能需要增加进程数。 |
phpfpm_max_active_processes |
允许的最大活跃进程数。 |
phpfpm_max_children_reached |
达到最大子进程数的次数。如果这个值不为零,说明 PHP-FPM 经常达到最大进程数,可能需要增加 pm.max_children 配置项的值。 |
phpfpm_max_listen_queue |
最大监听队列长度。 |
phpfpm_pool_state |
池状态 (idle, running, starting, stopping)。 |
phpfpm_slow_requests |
慢请求数,即处理时间超过 request_slowlog_timeout 配置项的请求数。如果这个值很高,说明 PHP 应用存在性能问题,需要进行优化。 |
phpfpm_start_since |
PHP-FPM 启动后的秒数。 |
phpfpm_start_time |
PHP-FPM 的启动时间。 |
phpfpm_total_processes |
总进程数,即活跃进程数和空闲进程数之和。 |
监控 Swoole
Swoole 是一个 PHP 的异步、并行、高性能网络通信引擎。监控 Swoole 的运行指标,可以帮助我们了解 Swoole 应用的性能状况。
1. 暴露 Swoole 的 Metrics
Swoole 本身没有提供类似 PHP-FPM 的 Status 页面,我们需要手动暴露 Swoole 的 Metrics。
可以使用 swoole_http_server 提供的 HTTP 服务,创建一个 endpoint 来暴露 Metrics。
<?php
use SwooleHttpServer;
use SwooleHttpRequest;
use SwooleHttpResponse;
$server = new Server("0.0.0.0", 9501);
$server->on("Request", function (Request $request, Response $response) {
if ($request->server['request_uri'] === '/metrics') {
$metrics = getSwooleMetrics(); // 获取 Swoole 的 Metrics 数据
$response->header("Content-Type", "text/plain");
$response->end($metrics);
} else {
$response->status(404);
$response->end();
}
});
$server->start();
function getSwooleMetrics(): string
{
// TODO: 实现获取 Swoole Metrics 数据的逻辑
// 例如:
// - 获取 worker 进程状态
// - 获取 task 队列长度
// - 获取连接数
// - 获取请求数
// - 获取内存使用情况
$worker_num = 4; // 假设配置了 4 个 worker 进程
$task_queue_length = rand(0, 100); // 模拟 task 队列长度
$connections = rand(0, 1000); // 模拟连接数
$requests = rand(0, 10000); // 模拟请求数
$memory_usage = rand(100, 200); // 模拟内存使用情况 (MB)
$metrics = "# HELP swoole_worker_num Number of worker processesn";
$metrics .= "# TYPE swoole_worker_num gaugen";
$metrics .= "swoole_worker_num " . $worker_num . "n";
$metrics .= "# HELP swoole_task_queue_length Length of the task queuen";
$metrics .= "# TYPE swoole_task_queue_length gaugen";
$metrics .= "swoole_task_queue_length " . $task_queue_length . "n";
$metrics .= "# HELP swoole_connections Number of active connectionsn";
$metrics .= "# TYPE swoole_connections gaugen";
$metrics .= "swoole_connections " . $connections . "n";
$metrics .= "# HELP swoole_requests Number of processed requestsn";
$metrics .= "# TYPE swoole_requests countern";
$metrics .= "swoole_requests " . $requests . "n";
$metrics .= "# HELP swoole_memory_usage Memory usage in MBn";
$metrics .= "# TYPE swoole_memory_usage gaugen";
$metrics .= "swoole_memory_usage " . $memory_usage . "n";
return $metrics;
}
注意:
- 你需要根据你的 Swoole 应用的实际情况,实现
getSwooleMetrics()函数,获取 Swoole 的 Metrics 数据。 - 上面的代码只是一个示例,用于演示如何暴露 Swoole 的 Metrics。你需要根据你的需求,添加更多的 Metrics。
# HELP和# TYPE是 Prometheus 要求的格式,用于描述 Metrics 的含义和类型。gauge类型表示可以上下波动的指标,例如 worker 进程数、task 队列长度、连接数、内存使用情况。counter类型表示单调递增的指标,例如请求数。
2. 配置 Prometheus
我们需要配置 Prometheus,让它定期从 /metrics 抓取指标数据。
打开 Prometheus 的配置文件(通常位于 /etc/prometheus/prometheus.yml),添加以下配置:
scrape_configs:
- job_name: 'swoole'
scrape_interval: 5s
static_configs:
- targets: ['your-domain.com:9501'] # 替换为你的 Swoole Metrics endpoint 的 URL
保存配置文件,并重启 Prometheus:
sudo systemctl restart prometheus
3. 在 Grafana 中创建仪表盘
现在,我们可以在 Grafana 中创建仪表盘,展示 Swoole 的运行指标。
- 添加 Prometheus 数据源到 Grafana。
- 创建新的仪表盘。
- 添加新的图表。
-
在图表的查询编辑器中,使用 PromQL 查询 Swoole 的指标,例如:
- Worker 进程数:
swoole_worker_num - Task 队列长度:
swoole_task_queue_length - 连接数:
swoole_connections - 请求数:
swoole_requests - 内存使用情况:
swoole_memory_usage
你可以根据自己的需求,创建各种图表,例如折线图、柱状图、仪表盘等。
- Worker 进程数:
Swoole 指标说明
| 指标名称 | 描述 |
|---|---|
swoole_worker_num |
Worker 进程数。 |
swoole_task_queue_length |
Task 队列长度,即等待被 Worker 进程处理的任务数。如果这个值持续很高,说明 Task 队列积压,可能需要增加 Worker 进程数或优化 Task 处理逻辑。 |
swoole_connections |
连接数,即当前活跃的 TCP 连接数。 |
swoole_requests |
请求数,即 Swoole 服务器处理的请求总数。 |
swoole_memory_usage |
内存使用情况,单位为 MB。 |
swoole_worker_status |
Worker 进程状态,可以用来监控 Worker 进程的运行情况,例如:swoole_worker_status{worker_id="0",state="idle"} 表示 worker_id 为 0 的 Worker 进程处于空闲状态。这里 state 可以是 idle(空闲)、busy(繁忙)、exit(退出)等。需要修改 getSwooleMetrics() 函数来暴露这些信息。 |
总结一下:监控为应用保驾护航
通过 Prometheus 和 Grafana,我们可以方便地监控 PHP-FPM 和 Swoole 的运行指标,从而更好地了解和优化我们的应用。这可以帮助我们及早发现问题、优化性能、进行容量规划、以及快速定位故障。 监控是保障应用稳定性和性能的重要手段,值得我们投入时间和精力。