Prometheus 监控 Hyperf 全栈实战:从协程指标到请求延迟的 Swoole 应用可观测性
Hyperf 是构建在 Swoole 协程引擎之上的高性能 PHP 微服务框架,支撑着无数高并发 API 和实时通信系统。然而,协程模型下的内存常驻、连接池耗尽、请求延迟抖动、协程数量泄漏等问题若缺乏量化监控,极易在流量洪峰中演变为雪崩。Hyperf 官方提供了hyperf/metric组件,原生集成 Prometheus,能够将 HTTP 请求指标、服务器状态、系统资源以及自定义业务指标以标准格式暴露。本文将带你从安装组件、配置多 Worker 聚合,到解读核心指标、构建 Grafana 大屏与告警落地,让 Swoole 驱动的 Hyperf 应用透明如玻璃。
1. 为什么选择 hyperf/metric + Prometheus?
- 官方出品,天然适配:
hyperf/metric专为 Hyperf 设计,完美处理协程环境和多 Worker 进程间的指标聚合。 - 低侵入性:通过中间件自动记录 HTTP 请求数、响应时间、状态码;通过 AOP 或手动埋点采集业务指标。
- 多 Worker 支持:内置 Redis 适配器,将各 Worker 进程的指标汇聚存储,再由一个独立的 Prometheus 端点暴露,解决 Swoole 多进程隔离问题。
- 灵活扩展:支持 Counter、Gauge、Histogram,以及自定义标签,可无缝嵌入服务、数据库、缓存等业务逻辑。
2. 安装与配置 hyperf/metric
2.1 安装组件
在 Hyperf 项目根目录执行:
composerrequire hyperf/metric安装后,需要发布配置文件:
php bin/hyperf.php vendor:publish hyperf/metric配置文件位于config/autoload/metric.php。
2.2 配置 Prometheus 驱动与 Redis 聚合
在多 Worker 模式下,每个 Worker 进程的指标相互独立。为了汇总所有 Worker 的指标,hyperf/metric支持使用Redis作为共享存储。编辑config/autoload/metric.php:
return['default'=>'prometheus','metric'=>['prometheus'=>['driver'=>Hyperf\Metric\Adapter\Prometheus\MetricFactory::class,'mode'=>Hyperf\Metric\Adapter\Prometheus\Constants::SCRAPE_MODE,// 或 PUSH_MODE'scrape_host'=>env('PROMETHEUS_SCRAPE_HOST','0.0.0.0'),'scrape_port'=>env('PROMETHEUS_SCRAPE_PORT','9502'),'redis_config'=>[// 多 worker 聚合使用 Redis'host'=>env('REDIS_HOST','127.0.0.1'),'port'=>(int)env('REDIS_PORT',6379),'auth'=>env('REDIS_AUTH',null),'db'=>(int)env('REDIS_DB',0),],'metric_interval'=>5,// 指标刷新间隔(秒)],],];SCRAPE_MODE:Prometheus 主动拉取指标,适合内部网络。redis_config:指定 Redis 连接信息,用于跨 Worker 指标聚合。metric_interval:Worker 将本地指标刷新到 Redis 的频率。
2.3 注册路由暴露/metrics
Hyperf 的/metrics端点需要注册一个控制器来处理。简单的方式是使用 Hyperf 自带的路由注解,并利用MetricFactory获取所有 Worker 汇总后的指标。
创建一个控制器app/Controller/MetricsController.php:
<?phpdeclare(strict_types=1);namespaceApp\Controller;useHyperf\Contract\ConfigInterface;useHyperf\HttpServer\Annotation\GetMapping;useHyperf\HttpServer\Contract\ResponseInterface;useHyperf\Metric\Adapter\Prometheus\MetricFactory;usePsr\Container\ContainerInterface;classMetricsController{publicfunction__construct(protectedContainerInterface$container,protectedConfigInterface$config){}#[GetMapping(path:"/metrics")]publicfunctionmetrics(ResponseInterface$response):\Psr\Http\Message\ResponseInterface{$factory=$this->container->get(MetricFactory::class);// 从 Redis 拉取所有 worker 的最新指标$registry=$factory->getRegistry();$renderer=new\Prometheus\RenderTextFormat();$result=$renderer->render($registry->getMetricFamilySamples());return$response->withHeader('Content-Type',\Prometheus\RenderTextFormat::MIME_TYPE)->withBody(new\Hyperf\Utils\Stream\SwooleStream($result));}}或者使用Hyperf\Metric\Middleware\MetricMiddleware自动记录 HTTP 请求(稍后说明)。重新启动 Hyperf 后,访问http://localhost:9502/metrics即可看到指标。
3. 自动采集 HTTP 请求指标
在config/autoload/middlewares.php中添加全局中间件:
return['http'=>[\Hyperf\Metric\Middleware\MetricMiddleware::class,],];这样每个 HTTP 请求会自动生成以下 Prometheus 指标(前缀可配置):
| 指标 | 含义 |
|---|---|
http_requests_total | 请求总数(按status,method,path分) |
http_request_duration_seconds(Histogram) | 请求处理时间分布 |
http_requests_in_progress(Gauge) | 当前正在处理的请求数 |
这些指标由中间件透明埋点,无需手动编码。
4. 核心系统指标与自定义业务指标
4.1 Swoole 服务器状态
Hyperf 的metric组件在启用后会自动上报一些 Swoole 进程信息(如 Worker 数、当前协程数),但可能需要额外配置。默认情况下,hyperf/metric可通过 AOP 或监听器获取:
swoole_server_worker_num(需自行暴露)swoole_coroutine_num
如需 Swoole 服务器指标,可创建一个定时任务或自定义指标,使用 Gauge 上报当前协程数等。但对于大部分场景,HTTP 中间件指标已足够。
4.2 自定义业务计数器
通过依赖注入MetricFactory,即可在业务代码中创建 Counter、Histogram。
useHyperf\Metric\Contract\MetricFactoryInterface;classOrderService{publicfunction__construct(protectedMetricFactoryInterface$factory){}publicfunctioncreateOrder(array$data):void{// 业务逻辑...// 递增订单计数器$counter=$this->factory->makeCounter('orders_processed_total',['status']);$counter->with('success')->inc();// 记录订单处理时间$timer=$this->factory->makeTimer('order_processing_seconds',['type']);$timer->with('standard')->start();// ... 业务$timer->with('standard')->end();}}这些自定义指标会和系统指标一起暴露在/metrics端点。
4.3 连接池指标
Hyperf 连接池(如数据库、Redis)的健康状态至关重要。可以通过hyperf/pool的事件或 AOP 将连接池长度、活跃连接数暴露为 Gauge。如使用hyperf/db,可以在配置中开启pool的监控并自己实现指标上报,或者等待社区插件。目前可参考自定义指标方式,在定时器中获取连接池统计并设置 Gauge。
5. 配置 Prometheus 抓取
在prometheus.yml中添加 Job:
scrape_configs:-job_name:'hyperf'scrape_interval:15smetrics_path:'/metrics'static_configs:-targets:['hyperf-app:9502']# 替换为实际 Hyperf 服务地址labels:app:'order-service'env:'production'如果 Hyperf 启用了认证,可在请求中添加basic_auth或在反向代理层处理。
6. Grafana 仪表盘推荐
由于 Hyperf 的指标与 Prometheus 标准客户端一致,可复用通用的 HTTP 服务仪表盘:
- PHP & Swoole Dashboard:Dashboard ID13320(社区贡献),结合了 HTTP 请求、Swoole 状态、系统资源等,适配 Hyperf。
- Microservice API Gateway:ID10456,若关注 QPS、错误率、延迟,可导入此面板,并修改指标前缀为
http_requests_total。 - 自定义 Hyperf 大屏:使用 Stat 面板显示 QPS、错误率;Graph 展示 P95 延迟;Table 列出各 API 响应时间。
导入后选择数据源,用变量app过滤服务。
7. 告警规则实战
groups:-name:hyperf_alertsrules:-alert:HyperfDownexpr:up{job="hyperf"}== 0for:1mlabels:severity:criticalannotations:summary:"Hyperf 服务 {{ $labels.instance }} 不可达"-alert:HyperfHighErrorRateexpr:rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m])>0.01for:5mlabels:severity:criticalannotations:summary:"Hyperf 服务 5xx 错误率超过 1% (当前 {{ $value }})"-alert:HyperfHighLatencyexpr:histogram_quantile(0.99,rate(http_request_duration_seconds_bucket[5m]))>1for:5mlabels:severity:warningannotations:summary:"Hyperf HTTP 请求 P99 延迟超过 1 秒"-alert:HyperfRequestSurgeexpr:rate(http_requests_total[5m])>1000for:5mlabels:severity:infoannotations:summary:"Hyperf 请求速率超过 1000 QPS,关注连接池压力"-alert:HyperfCoroutineLeak# 需要自定义暴露 coroutine_num 指标,示例假设指标名为 hyperf_coroutine_numexpr:hyperf_coroutine_num>5000for:10mlabels:severity:warningannotations:summary:"Hyperf 协程数量超过 5000,可能存在泄漏"可根据实际业务调整阈值。
8. 进阶:多 Worker 聚合性能优化与安全
8.1 多 Worker 聚合的 Redis 压力
metric_interval控制每个 Worker 将本地指标推送到 Redis 的频率。如果 Worker 数非常多(如 100+),且metric_interval设为 5 秒,会对 Redis 产生较多写入。建议:
- 适当增大
metric_interval至 10~15 秒。 - 使用专用的 Redis 实例或数据库,避免与业务缓存竞争。
- 监控 Redis 的吞吐和延迟。
8.2 安全加固
- Prometheus 抓取端口(9502)应仅内网可达,使用防火墙或 Hyperf 的 IP 白名单中间件保护。
- 可配合 Nginx 反代
/metrics,添加 Basic Auth。 - 确保 Redis 密码强度,且 Redis 端口不暴露于公网。
8.3 其他监控整合
- 结合 Node Exporter 监控 Hyperf 运行的宿主机资源(CPU、内存、网络)。
- 配合 MySQL/Redis Exporter 监控 Hyperf 依赖的后端服务。
- 使用 Loki 收集 Hyperf 日志,通过 Grafana 关联指标和日志。
8.4 升级与兼容性
hyperf/metric依赖prometheus/client_php,版本更新需注意兼容性。建议定期更新 Hyperf 版本以获得最新指标能力和性能改进。
9. 总结
通过 Hyperf 官方hyperf/metric组件,Swoole 驱动的 PHP 应用首次获得了与 Java/Go 同等级别的原生 Prometheus 集成。无论是自动捕获的 HTTP 请求指标,还是自定义的业务订单计数器,亦或是协程与连接池的内部状态,都能无缝汇入 Prometheus 生态。Grafana 大屏上,每一个 API 的延迟、每一个错误码的突增都一目了然;Alertmanager 则在异常时第一时间告警。从此,Hyperf 微服务不再“盲飞”,全栈可观测性地块中又添上了一块坚实的 PHP 拼图。