本文目录导读:

实现PHP API性能监控,通常从四个维度切入:请求响应时间、吞吐量(QPS)、错误率、资源消耗(CPU/内存),以下是几种主流且实用的实现方案,按从简单到复杂的顺序排列:
基础方案:Nginx + 日志分析(最轻量)
如果不想修改PHP代码,可以直接利用Nginx的访问日志。
配置步骤:
# nginx.conf 日志格式增加响应时间
log_format apimon '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'$request_time $upstream_response_time';
access_log /var/log/nginx/api-access.log apimon;
分析工具: 可以使用 goaccess 或 ngxtop 实时分析:
# 安装 goaccess goaccess /var/log/nginx/api-access.log --log-format=COMBINED --real-time-html
适用场景: 快速排查、无侵入、无需修改代码。
中间件方案:APM 探针(推荐生产使用)
使用成熟的APM(应用性能管理)工具,自动收集函数调用链、数据库查询、外部HTTP请求耗时。
| 工具 | 特点 | 安装方式 |
|---|---|---|
| Pinpoint | 对PHP支持好,字节码注入,无需改代码 | 安装C扩展 + Agent |
| SkyWalking | Apache顶级项目,PHP Agent成熟 | pecl install skywalking |
| OneAPM / 听云 | 国内SaaS服务,开箱即用 | 安装扩展 + 配置license |
| Datadog | 国际主流,功能全面 | composer require datadog/dd-trace |
示例(SkyWalking):
# 安装PHP扩展 pecl install skywalking # 配置 php.ini extension=skywalking.so skywalking.collector=http://localhost:12800 skywalking.service_name=my-api
适用场景: 微服务架构、需要追踪分布式调用链。
自定义埋点方案(灵活可控)
自己编写监控中间件,记录关键指标并发送到时序数据库。
核心实现代码(使用 Prometheus + Grafana)
<?php
// 中间件类
class ApiMonitor
{
private $startTime;
private $redis;
public function __construct()
{
$this->startTime = microtime(true);
$this->redis = new \Redis();
$this->redis->connect('127.0.0.1', 6379);
}
public function handle($request, $next)
{
// 记录请求开始
$this->recordRequest($request);
// 执行实际逻辑
$response = $next($request);
// 记录请求结束
$duration = (microtime(true) - $this->startTime) * 1000; // ms
$this->recordDuration($request->getPath(), $duration);
$this->recordMemory(memory_get_peak_usage(true));
return $response;
}
private function recordRequest($request)
{
$key = 'api:counter:' . date('YmdHi');
$this->redis->incr($key);
$this->redis->expire($key, 120);
}
private function recordDuration($path, $ms)
{
// 发送到 Prometheus Pushgateway
$this->pushToPrometheus([
'name' => 'api_request_duration_ms',
'labels' => ['path' => $path],
'value' => $ms
]);
}
private function pushToPrometheus($metrics)
{
$payload = "# HELP api_request_duration_ms API request duration\n";
$payload .= "# TYPE api_request_duration_ms gauge\n";
$payload .= "api_request_duration_ms{path=\"{$metrics['labels']['path']}\"} {$metrics['value']}\n";
$ch = curl_init('http://prometheus-pushgateway:9091/metrics/job/api-monitor');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
curl_close($ch);
}
}
在框架中注册(以 Laravel 为例)
// app/Http/Kernel.php
protected $middleware = [
\App\Http\Middleware\ApiMonitor::class,
];
适用场景: 已有监控基础设施、需要针对业务定制指标。
全链路方案:OpenTelemetry(未来趋势)
OpenTelemetry 是CNCF的标准化可观测性框架,支持多语言。
集成步骤:
# 安装OTel PHP SDK composer require open-telemetry/sdk open-telemetry/exporter-otlp # 启动收集器(Docker) docker run -p 4317:4317 otel/opentelemetry-collector
PHP代码集成:
<?php
use OpenTelemetry\API\Trace\Span;
use OpenTelemetry\API\Trace\StatusCode;
use OpenTelemetry\SDK\Trace\TracerProvider;
use OpenTelemetry\SDK\Trace\SpanProcessor\BatchSpanProcessor;
use OpenTelemetry\SDK\Trace\Exporter\ConsoleSpanExporter;
// 初始化Tracer
$tracer = (new TracerProvider(
new BatchSpanProcessor(
new ConsoleSpanExporter()
)
))->getTracer('api-monitor');
// 创建Span
$span = $tracer->spanBuilder('/api/users')->startSpan();
$span->setAttribute('http.method', $_SERVER['REQUEST_METHOD']);
// ... 业务逻辑 ...
$span->setStatus(StatusCode::STATUS_OK);
$span->end();
关键指标采集清单
无论选择哪种方案,建议至少采集以下指标:
| 指标 | 获取方式 | 告警阈值 |
|---|---|---|
| P99响应时间 | percentile(response_time, 0.99) |
> 2000ms |
| 错误率 | error_count / total_count * 100 |
> 1% |
| 慢查询数量 | 数据库连接池统计 | > 5次/分钟 |
| PHP进程数 | ps aux \| grep php-fpm \| wc -l |
> 可用CPU核心数*10 |
| 内存泄漏趋势 | memory_get_usage(true) 连续采样 |
持续增长 |
| OPcache命中率 | opcache_get_status()['opcache_statistics']['hits'] |
< 90% |
推荐组合
根据团队资源选择:
- 小团队(<5人): Nginx日志 + Prometheus + Grafana(免费、轻量)
- 中大型团队: SkyWalking + Elastic APM(开源、功能全)
- SaaS方案: Datadog / New Relic(付费但省心)
注意事项
- 不要阻塞主流程:使用异步写入(如
register_shutdown_function)或消息队列 - 采样率控制:高并发API设置采样率(如10%),避免监控本身成为性能瓶颈
- 敏感信息过滤:不要在日志中输出用户密码、Token等
- 监控自身健康:监控系统宕机时应降级,不要影响业务API
需要具体的代码模板(如Laravel中间件完整实现)或监控仪表盘配置JSON吗?