PHP应用监控实战:利用Prometheus和Grafana采集FPM与Swoole的运行指标

好的,下面是一篇关于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 的运行指标。

  1. 添加 Prometheus 数据源到 Grafana。
  2. 创建新的仪表盘。
  3. 添加新的图表。
  4. 在图表的查询编辑器中,使用 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 的运行指标。

  1. 添加 Prometheus 数据源到 Grafana。
  2. 创建新的仪表盘。
  3. 添加新的图表。
  4. 在图表的查询编辑器中,使用 PromQL 查询 Swoole 的指标,例如:

    • Worker 进程数: swoole_worker_num
    • Task 队列长度: swoole_task_queue_length
    • 连接数: swoole_connections
    • 请求数: swoole_requests
    • 内存使用情况: swoole_memory_usage

    你可以根据自己的需求,创建各种图表,例如折线图、柱状图、仪表盘等。

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 的运行指标,从而更好地了解和优化我们的应用。这可以帮助我们及早发现问题、优化性能、进行容量规划、以及快速定位故障。 监控是保障应用稳定性和性能的重要手段,值得我们投入时间和精力。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注