本文目录导读:

在 PHP 项目中实现性能监控,通常涉及对应用层的追踪(如执行时间、SQL 慢查询)、服务器层的监控(CPU、内存)以及业务层的监控(接口响应时间、错误率)。
以下是一个从简单到深入的实践指南,包含常用的工具和代码示例:
基础的“脚本内”监控(无需安装扩展)
适合快速排查问题,可以作为临时日志写入文件。
<?php
// 1. 在项目入口文件(如 index.php)顶部
define('START_TIME', microtime(true));
define('START_MEMORY', memory_get_usage());
// 2. 在脚本结束处注册 shutdown 函数
register_shutdown_function(function () {
$executionTime = (microtime(true) - START_TIME) * 1000 . ' ms';
$memoryUsage = (memory_get_usage() - START_MEMORY) / 1024 . ' KB';
// 仅记录慢请求(> 500ms)
if ($executionTime > 500) {
$log = sprintf("[%s] URL: %s | Time: %s | Memory: %s\n",
date('Y-m-d H:i:s'),
$_SERVER['REQUEST_URI'] ?? 'cli',
$executionTime,
$memoryUsage
);
file_put_contents('/tmp/slow_requests.log', $log, FILE_APPEND);
}
});
缺点:开销较大,不适合生产环境全面启用,通常用于开发环境或 Debug 模式。
集成 APM 工具(生产环境推荐)
这是最成熟、影响最小的方案,以下工具已广泛用于 PHP 生态:
| 工具 | 特点 | 安装方式 |
|---|---|---|
| Pinpoint | 开源,韩国团队开发,对 PHP 支持良好,支持分布式追踪 | 安装 PHP 扩展 pinpoint_php |
| SkyWalking | Apache 顶级项目,支持 PHP 8+ | 使用 skywalking_php 扩展 |
| New Relic | SaaS 商业产品,功能强大,一键集成 | 安装 PHP 扩展 newrelic |
| Datadog | SaaS 商业产品,适合已有 Datadog 体系的团队 | 安装 datadog-php 扩展 |
| OpenTelemetry | 目前最推荐的开源标准,可以导出数据到 Prometheus、Jaeger | 通过 Composer 安装 open-telemetry/opentelemetry-auto-... |
示例:使用 OpenTelemetry(零代码侵入,自动监控)
# 1. 安装扩展(以 Laravel 为例) composer require open-telemetry/opentelemetry-auto-laravel # 2. 配置导出端(例如导出到 Zipkin 或 Jaeger) export OTEL_PHP_AUTOLOAD_ENABLED=true export OTEL_SERVICE_NAME=my-php-app export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 # 3. 运行项目,自动开始采集 Span php artisan serve
针对数据库/慢查询的监控
大部分 PHP 性能瓶颈在数据库。
方法 1:框架层监控(Laravel / Symfony)
// Laravel 的 DB 查询日志
\DB::listen(function ($query) {
if ($query->time > 1000) { // 超过 1 秒的慢查询
\Log::warning('Slow Query', [
'sql' => $query->sql,
'bindings' => $query->bindings,
'time' => $query->time
]);
}
});
方法 2:数据库端监控
- MySQL Slow Query Log:直接在 MySQL 配置中开启,然后使用
pt-query-digest分析日志。 - 性能 Schema:通过
performance_schema表实时查询慢语句。
服务器基础指标监控
PHP 自身不能直接监控服务器硬件,但可以通过以下方式配合:
- 使用
sys_getloadavg():在 PHP 中获取系统负载。 - 读取
/proc/meminfo、/proc/stat:获取 CPU 和内存使用情况(可在小流量环境使用)。 - 配合
telegraf+Prometheus:最推荐的方式,Telegraf 收集服务器指标,PHP 可以通过 Prometheus 客户端库暴露业务指标(如请求总数、错误率)。
构建轻量级业务监控(Prometheus + PHP)
如果你不想使用商业 APM,这是一个灵活的开源方案。
// 安装 Prometheus PHP 客户端
composer require promphp/prometheus_client_php
// 在项目入口记录指标
$registry = new Prometheus\CollectorRegistry(new Prometheus\Storage\APC());
// 定义计数器
$counter = $registry->registerCounter('app', 'requests_total', 'Total requests', ['method', 'endpoint']);
// 在路由处理时增加
$counter->inc(['GET', '/api/users']);
// 暴露指标端点(如 /metrics)
route('/metrics', function () use ($registry) {
header('Content-Type: text/plain');
echo $registry->renderText();
});
然后使用 Prometheus 拉取此端点,Grafana 可视化。
实战建议
-
分层监控,不要只盯着代码:
- 入口:Nginx/Apache 请求日志(记录
$request_time)。 - 应用:PHP-FPM 状态页(
/status)查看 pool 繁忙程度。 - 数据库:MySQL 监控(查询缓存、慢查询)。
- 缓存:Redis/Memcached 命中率。
- 入口:Nginx/Apache 请求日志(记录
-
从最容易出问题的地方开始:
- 先监控 慢查询(SQL 时间 > 1s)。
- 再监控 高内存消耗(
memory_get_peak_usage(true) > 256M)。 - 最后监控 外部 HTTP 调用(cURL 请求时间 > 2s)。
-
生产环境注意事项:
- 不要在生产环境频繁使用
echo打点,会引入性能损耗。 - 使用采样,例如只记录 1% 的请求(通过
rand(1,100) == 1过滤)。 - 异步写入,监控数据写入数据库或发送到 APM 服务器时,应该使用非阻塞方式(如 UDP、消息队列)。
- 不要在生产环境频繁使用
选择合适的方案
| 场景 | 推荐方案 |
|---|---|
| 个人博客/小项目 | 基础 microtime + 慢查询日志 + Nginx 日志分析 |
| 中型团队/追求性价比 | OpenTelemetry + Jaeger(开源)或 Datadog(付费) |
| 大型分布式系统 | 必选 APM 工具:Pinpoint 或 SkyWalking |
| 不想装任何扩展 | 只依赖框架日志(Laravel Telescope、Symfony Profiler) |
最直接的行动项:今天就在你的项目里加入一个简单的 slow_request 日志(response_time > 1s),这通常是发现性能问题的起点。