ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Hyperf 服务监控组件 hyperf/metric 全指南:Prometheus、StatsD、InfluxDB 多后端接入与业务指标采集实战

Hyperf 服务监控组件 hyperf/metric 全指南:Prometheus、StatsD、InfluxDB 多后端接入与业务指标采集实战 后端Web框架微服务RPC框架异步编程【免费下载链接】hyperf A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease.项目地址https://gitcode.com/hyperf/hyperf点击查看免费下载在微服务体系治理中服务的可观测性是核心诉求之一。作为运维者很难直观掌握每一个服务的健康状态而业界围绕 telemetry遥测与 monitoring监控已经沉淀了大量云原生方案。Hyperf 的hyperf/metric组件正是对这一能力的抽象它把可观测性、遥测与监控的关键支柱收敛为统一接口让开发者可以快速接入现有监控基础设施Prometheus、StatsD、InfluxDB 等同时避免与任何特定供应商强绑定。阅读本文后你将掌握如何安装并配置该组件、如何用三种后端驱动Prometheus / StatsD / InfluxDB采集与上报指标、如何通过中间件与注解统计 HTTP 请求与业务调用、如何自定义上报链路以及如何在 Grafana 中一键导入现成仪表盘。组件定位与设计理念hyperf/metric是 Hyperf 体系中的指标Metrics组件位于仓库 src/metric 目录。它解决的核心问题是在超高性能协程框架中如何以统一的编程模型向不同监控后端上报指标而不必在业务代码中散落各后端的专有 API。从 composer.json 可以看到组件面向 PHP 8.2关键字为prometheus、statsd、metrics、influxdb并通过suggest声明了各驱动所需的三方依赖。组件本身只负责「抽象 采集 分发」具体后端的差异被适配器Adapter隔离在src/metric/src/Adapter/目录下Prometheus、StatsD、InfluxDB、NoOp、RemoteProxy五套实现这正是其不锁定供应商的架构根基。安装与初始化通过 Composer 安装组件composer require hyperf/metrichyperf/metric本身是可独立安装的组件包随后按需安装对应后端的客户端依赖# Prometheus composer require promphp/prometheus_client_php # StatsD 依赖 composer require domnikl/statsd # InfluxDB 依赖 composer require influxdb/influxdb-php补充说明仓库内 src/metric/composer.json 的suggest中提示的是slickdeals/statsd与influxdata/influxdb-client-php与文档示例中的包名略有差异——前者同样提供Domnikl\Statsd命名空间后两者对应不同版本的 InfluxDB 客户端。实际以你所在项目的依赖解析结果为准。发布组件配置文件若项目中尚不存在配置文件执行以下命令生成config/autoload/metric.phpphp bin/hyperf.php vendor:publish hyperf/metric发布动作由 ConfigProvider.php 中的publish节点定义源文件即 src/metric/publish/metric.php。同时该 ConfigProvider 还会注册以下内容依赖注入绑定MetricFactoryInterface→MetricFactoryPickerPrometheus\Storage\Adapter→InMemory默认内存存储StatsD 连接 →UdpSocketAOP 切面CounterAnnotationAspect、HistogramAnnotationAspect支撑注解埋点事件监听器OnPipeMessage、OnMetricFactoryReady、OnWorkerStart等常驻进程MetricProcess即独立监控进程。核心配置解析顶层选项default env(METRIC_DRIVER, prometheus),default的值对应配置文件中metric下标里某个驱动配置的key即当前生效的驱动名。可以随时通过环境变量切换驱动而无需改动业务代码。use_standalone_process env(TELEMETRY_USE_STANDALONE_PROCESS, true),use_standalone_process是否启用「独立监控进程」。强烈建议开启。若关闭指标采集与上报将由 Worker 进程内联完成参见 OnWorkerStart.php 中use_standalone_process为 false 时调用spawnHandle()的分支。enable_default_metric env(TELEMETRY_ENABLE_DEFAULT_TELEMETRY, true),enable_default_metric是否采集默认指标。默认指标包括内存使用量、系统 CPU 负载以及 Swoole Server 与 Swoole Coroutine 的相关指标。在源码层面OnWorkerStart.php 会以default_metric_interval为周期定时写入worker_request_count、worker_dispatch_count、memory_usage、memory_peak_usage、gc_runs、gc_collected、ru_utime_tv_usec来自getrusage()等一组系统级指标。default_metric_interval env(DEFAULT_METRIC_INTERVAL, 5),default_metric_interval默认指标的推送周期单位为秒下文各驱动的push_interval同理。完整发布配置含增强项官方发布文件 src/metric/publish/metric.php 比文档示例更完整其中还包含enable_command_metricMETRIC_ENABLE_COMMAND_METRIC默认 true是否在命令行场景启用指标buffer_intervalMETRIC_BUFFER_INTERVAL默认 5与buffer_sizeMETRIC_BUFFER_SIZE默认 200仅在use_standalone_process true时生效用于控制 Worker 向独立监控进程投递指标数据的缓冲节奏与容量noop驱动将default指向noop即可临时禁用指标采集实现零成本开关Prometheus 的redis_config、redis_prefix、redis_gather_key_suffix用于自定义模式下的 Redis 存储配置。注意文档示例中的环境变量名如TELEMETRY_USE_STANDALONE_PROCESS、TELEMETRY_ENABLE_DEFAULT_TELEMETRY与发布文件中的默认值METRIC_USE_STANDALONE_PROCESS、METRIC_ENABLE_DEFAULT_METRIC并不完全一致两者都可按需调整请以实际vendor:publish生成的config/autoload/metric.php为准。三大后端驱动配置配置 Prometheus将 Prometheus 专属配置放入metric下标use Hyperf\Metric\Adapter\Prometheus\Constants; return [ default env(METRIC_DRIVER, prometheus), use_standalone_process env(TELEMETRY_USE_STANDALONE_PROCESS, true), enable_default_metric env(TELEMETRY_ENABLE_DEFAULT_TELEMETRY, true), default_metric_interval env(DEFAULT_METRIC_INTERVAL, 5), metric [ prometheus [ driver Hyperf\Metric\Adapter\Prometheus\MetricFactory::class, mode Constants::SCRAPE_MODE, namespace env(APP_NAME, skeleton), scrape_host env(PROMETHEUS_SCRAPE_HOST, 0.0.0.0), scrape_port env(PROMETHEUS_SCRAPE_PORT, 9502), scrape_path env(PROMETHEUS_SCRAPE_PATH, /metrics), push_host env(PROMETHEUS_PUSH_HOST, 0.0.0.0), push_port env(PROMETHEUS_PUSH_PORT, 9091), push_interval env(PROMETHEUS_PUSH_INTERVAL, 5), ], ], ];Prometheus 支持三种操作模式常量定义见 Constants.phpSCRAPE_MODE 1、PUSH_MODE 2、CUSTOM_MODE 3。Scrape 模式Prometheus 官方推荐设置mode Constants::SCRAPE_MODE并配置抓取地址scrape_host、抓取端口scrape_port、抓取路径scrape_pathPrometheus 即可按配置通过 HTTP 拉取全部指标。注意在异步风格协程 Server下scrape 模式必须开启独立进程即use_standalone_process true。从实现看Prometheus MetricFactory.php 的scrapeHandle()会在scrape_host:scrape_port上起一个内置 HTTP Server以RenderTextFormat渲染CollectorRegistry中的指标它还会检查该端口是否与server.servers中业务服务端口冲突并输出告警日志。Push 模式设置mode Constants::PUSH_MODE并配置推送地址push_host、推送端口push_port、推送周期push_interval。Push 模式仅推荐用于离线任务offline task。其实现位于pushHandle()按push_interval周期性地向 Pushgateway 发起 PUT 请求请求 URL 形如http://host:port/metrics/job/{namespace}/ip/{ip}/pid/{pid}并校验响应码必须为 200 或 202。Custom 模式设置mode Constants::CUSTOM_MODE。在该模式下组件只负责指标采集上报动作完全交由使用者处理——例如通过自定义路由暴露指标或把指标暂存到 Redis 由独立服务集中上报。本文「自定义上报」一节给出对应示例。配置 StatsDreturn [ default env(METRIC_DRIVER, statd), use_standalone_process env(TELEMETRY_USE_STANDALONE_PROCESS, true), enable_default_metric env(TELEMETRY_ENABLE_DEFAULT_TELEMETRY, true), metric [ statsd [ driver Hyperf\Metric\Adapter\StatsD\MetricFactory::class, namespace env(APP_NAME, skeleton), udp_host env(STATSD_UDP_HOST, 127.0.0.1), udp_port env(STATSD_UDP_PORT, 8125), enable_batch env(STATSD_ENABLE_BATCH, true), push_interval env(STATSD_PUSH_INTERVAL, 5), sample_rate env(STATSD_SAMPLE_RATE, 1.0), ], ], ];StatsD 目前仅支持 UDP 模式需要配置 UDP 地址udp_host、UDP 端口udp_port、是否批量推送enable_batch用于减少请求数量、批量推送周期push_interval、采样率sample_rate。发布配置中还可选timeout与persistent连接参数。从 StatsD MetricFactory.php 可以看到handle()在开启批量模式时会按push_interval周期循环执行startBatch()/endBatch()发布文件同时会创建Domnikl\Statsd\Connection\UdpSocket作为默认 UDP 连接。配置 InfluxDBreturn [ default env(METRIC_DRIVER, influxdb), use_standalone_process env(TELEMETRY_USE_STANDALONE_PROCESS, true), enable_default_metric env(TELEMETRY_ENABLE_DEFAULT_TELEMETRY, true), metric [ influxdb [ driver Hyperf\Metric\Adapter\InfluxDB\MetricFactory::class, namespace env(APP_NAME, skeleton), host env(INFLUXDB_HOST, 127.0.0.1), port env(INFLUXDB_PORT, 8086), username env(INFLUXDB_USERNAME, ), password env(INFLUXDB_PASSWORD, ), dbname env(INFLUXDB_DBNAME, true), push_interval env(INFLUXDB_PUSH_INTERVAL, 5), ], ], ];InfluxDB 默认使用 HTTP 模式需要配置地址host、端口port注意InfluxDB 通常使用 HTTP 端口 8086、用户名username、密码password、数据库dbname、批量推送周期push_interval。版本提示当前发布配置文件 src/metric/publish/metric.php 中 InfluxDB 段的字段为token、bucket、org对应 InfluxDB 2.x 的鉴权与组织模型文档示例中的username/password/dbname则对应 1.x 风格请根据实际部署版本选择。底层抽象Counter / Gauge / Histogram组件抽象出三种最常用的指标类型确保业务代码与具体实现解耦Counter计数器描述单调递增的指标例如 HTTP 请求总数。interface CounterInterface { public function with(string ...$labelValues): self; public function add(int $delta); }Gauge仪表描述随时间可升可降的指标例如连接池当前可用连接数。interface GaugeInterface { public function with(string ...$labelValues): self; public function set(float $value); public function add(float $delta); }Histogram直方图描述对某事件持续观测得到的统计分布通常以百分位或 bucket 呈现例如 HTTP 请求延迟。interface HistogramInterface { public function with(string ...$labelValues): self; public function put(float $sample); }对应的契约文件位于 src/metric/src/Contract 目录CounterInterface.php、GaugeInterface.php、HistogramInterface.php、MetricFactoryInterface.php。统一入口MetricFactoryInterface提供三个工厂方法public function makeCounter($name, $labelNames): CounterInterface; public function makeGauge($name, $labelNames): GaugeInterface; public function makeHistogram($name, $labelNames): HistogramInterface;工厂方法会通过with(...$labelValues)绑定标签值label后续调用add/set/put写入具体数值。以 Prometheus 适配器为例Prometheus MetricFactory.php 在创建指标时会自动附带 help 描述如count xxx、gauge xxx、measure xxx并统一使用 snake_case 的命名空间getNamespace()会将非法字符替换为下划线MetricFactoryTest.php 中验证了Hello-World!→hello__world_的转换。配置中间件自动采集 HTTP 指标配置好驱动后只需注册中间件即可为请求开启 Histogram 统计。编辑config/autoload/middlewares.php在httpServer 中启用?php declare(strict_types1); return [ http [ \Hyperf\Metric\Middleware\MetricMiddleware::class, ], ];该中间件的统计维度包含request_status、request_path、request_method。实现细节见 MetricMiddleware.php它默认以500作为兜底状态码防止未捕获异常时缺失维度request_path优先取路由分发结果Dispatched中的路由定义未匹配时记为not_found并用Timer见 Timer.php记录耗时写入http_requests直方图同时维护CoroutineServerStatsCoroutineServerStats.php中的连接数、请求数、响应数等统计。重要提醒如果你的服务存在过多request_path建议重写该中间件并移除request_path维度否则过高的基数cardinality会导致内存溢出。业务指标自定义埋点通过 HTTP 中间件采集遥测只是该组件能力的冰山一角。你可以注入Hyperf\Metric\Contract\MetricFactoryInterface采集自身业务指标例如「创建订单数」「广告点击数」?php declare(strict_types1); namespace App\Controller; use App\Model\Order; use Hyperf\Di\Annotation\Inject; use Hyperf\Metric\Contract\MetricFactoryInterface; class IndexController extends AbstractController { #[Inject] private MetricFactoryInterface $metricFactory; public function create(Order $order) { $counter $this-metricFactory-makeCounter(order_created, [order_type]); $counter-with($order-type)-add(1); // Logika order... } }上述示例采集的是单个请求生命周期内的指标。有些指标则面向完整的生命周期例如异步队列长度、商品库存量。这类场景可以监听MetricFactoryReady事件?php declare(strict_types1); namespace App\Listener; use Hyperf\Event\Contract\ListenerInterface; use Hyperf\Metric\Event\MetricFactoryReady; use Psr\Container\ContainerInterface; use Redis; class OnMetricFactoryReady implements ListenerInterface { protected ContainerInterface $container; public function __construct(ContainerInterface $container) { $this-container $container; } public function listen(): array { return [ MetricFactoryReady::class, ]; } public function process(object $event) { $redis $this-container-get(Redis::class); $gauge $event -factory -makeGauge(queue_length, [driver]) -with(redis); while (true) { $length $redis-llen(queue); $gauge-set($length); sleep(1); } } }MetricFactoryReady事件定义在 src/metric/src/Event/MetricFactoryReady.php事件携带一个「已就绪的工厂」MetricFactoryInterface。该事件由独立监控进程MetricProcess.php在handle()中派发也会在非独立进程模式下由 OnWorkerStart.php 对 worker 0 派发从而保证监听器里的长循环能拿到真实可用的工厂实例。工程上更严谨的做法是不要直接llenRedis 查询队列长度而应通过队列驱动DriverInterface::info()方法获取队列长度——上面仅是简单演示。组件源码src/metric/src/Listener/下提供了完整示例例如 QueueWatcher.php 会周期性地将队列的waiting、delayed、failed、timeout写入四个 Gauge 指标PoolWatcher.php及其子类DBPoolWatcher、RedisPoolWatcher则按default_metric_interval周期上报连接池的connections_in_use、connections_in_waiting、max_connections。组件还提供了门面式的便捷类 Metric.phpBeta 特性API 可能变化Metric::count()、Metric::gauge()、Metric::shift()、Metric::put()、Metric::time()可一次性创建并写入指标其中Metric::time($name, $func)借助Timer自动统计回调执行耗时。注解埋点统计调用次数与耗时你可以在类或方法上使用#[Counter(namestat_name_here)]与#[Histogram(namestat_name_here)]注解让切面自动统计该方法的调用次数与执行耗时#[Counter(name: order_create_count)] public function createOrder() { /* ... */ } #[Histogram(name: order_create_duration)] public function processOrder() { /* ... */ }实现上CounterAnnotationAspect.php 与 HistogramAnnotationAspect.php 分别监听对应注解指标名缺省时自动生成「类名::方法名」的 snake_case 形式标签维度固定为class与methodHistogram 切面借助Timer在方法执行前后自动计时。注解本身的定义见 src/metric/src/Annotation 目录Counter.php、Histogram.php均为#[Attribute(Attribute::TARGET_CLASS | Attribute::TARGET_METHOD)]。注解机制依赖hyperf/di具体用法可参考 Annotation 章节。自定义 Histogram Bucket仅 Prometheus 驱动使用 Prometheus 的 Histogram 时有时需要自定义 bucket。可以借助注入的CollectorRegistry在服务启动前自行注册同名 Histogram 并设置所需 bucket。之后使用MetricFactory时同名 Histogram 会直接命中你注册的实例?php namespace App\Listener; use Hyperf\Config\Annotation\Value; use Hyperf\Event\Contract\ListenerInterface; use Hyperf\Framework\Event\BeforeMainServerStart; use Prometheus\CollectorRegistry; class OnMainServerStart implements ListenerInterface { protected $registry; public function __construct(CollectorRegistry $registry) { $this-registry $registry; } public function listen(): array { return [ BeforeMainServerStart::class, ]; } public function process(object $event) { $this-registry-registerHistogram( config(metric.metric.prometheus.namespace), test, help_message, [labelName], [0.1, 1, 2, 3.5] ); } }随后执行$metricFactory-makeHistogram(test)返回的即为你先前注册的自定义 bucket 直方图。自定义上报仅 Prometheus 驱动将 Prometheus 驱动模式设为Constants::CUSTOM_MODE后指标上报完全由你掌控。以下演示把指标存储到 Redis再在 Worker 中新增一个 HTTP 路由返回由 Prometheus 渲染的指标文本。使用 Redis 存储指标指标存储介质由Prometheus\Storage\Adapter接口定义默认使用内存存储InMemory。在config/autoload/dependencies.php中覆盖为 Redis 存储?php return [ Prometheus\Storage\Adapter::class Hyperf\Metric\Adapter\Prometheus\RedisStorageFactory::class, ];RedisStorageFactory.php 会读取metric.metric.prometheus.redis_config默认default、redis_prefix、redis_gather_key_suffix等配置通过Hyperf\Redis\RedisFactory获取对应连接并包装为 Prometheus 的 Redis 存储适配器Redis.php。在 Worker 中新增 /metrics 路由在config/routes.php中添加 Prometheus 路由注意若要在 Worker 中读取指标需要自行解决多个 Worker 之间的状态共享问题——一种方案就是上文所述把状态存到 Redis。?php use Hyperf\HttpServer\Router\Router; Router::get(/metrics, function(){ $registry Hyperf\Context\ApplicationContext::getContainer()-get(Prometheus\CollectorRegistry::class); $renderer new Prometheus\RenderTextFormat(); return $renderer-render($registry-getMetricFamilySamples()); });在 Grafana 中一键创建监控面板仅 Prometheus 驱动如果你开启了默认指标enable_default_metric truehyperf/metric已经为你准备了一份开箱即用的 Grafana 面板。仓库内的仪表盘定义文件位于 src/metric/grafana.json将其导入 Grafana 即可直接使用。该仪表盘覆盖两类面板一类是核心资源与运行状态系统负载百分比、内存使用量、内存峰值、当前协程数量、连接数、接受请求计数、关闭请求计数等另一类是按路径划分的请求概览各路径请求数、错误数、P50/P90/P99 延迟、成功率。注意事项如果需要在自定义命令hyperf/command中使用本组件采集指标启动命令时需追加命令行参数--enable-event-dispatcher否则事件分发包括MetricFactoryReady不会被启用指标链路无法工作。在命令行场景下使用 Prometheus scrape 模式时组件会输出告警Using Prometheus scrape mode in a command. This will stop the command from terminating gracefully.见 Prometheus MetricFactory.php 的handle()因为 scrape 模式内置的指标 HTTP 服务会阻塞命令优雅退出此时建议使用 push 模式或 custom 模式。MetricFactoryPickerMetricFactoryPicker.php是工厂选择的枢纽在非协程上下文返回NoOp工厂当use_standalone_process true但未检测到已注册进程且非命令行时也回退为NoOp属于配置错误的兜底在 Worker 中则返回RemoteProxy工厂将指标数据通过PipeMessage消息通道投递给独立监控进程由 OnPipeMessage.php 接收并写回真实工厂从而保证 Worker 不受上报阻塞的影响。独立监控进程由 MetricProcess.php 承载进程名metric数量 1仅在$server instanceof Swoole\Server且use_standalone_process true时启用异步协程 Server 场景下则通过OnCoroutineServerStart等监听器完成默认指标采集。小结hyperf/metric用一个轻量的抽象层把 Prometheus、StatsD、InfluxDB 的差异封装在适配器内部向上提供 Counter / Gauge / Histogram 三种通用指标模型向外支持 scrape、push、custom 三种上报模式。结合本文提到的中间件、注解、MetricFactoryReady事件、自定义 bucket、Redis 存储与 Grafana 面板你可以快速构建一套从「系统默认指标」到「业务自定义指标」的完整服务可观测体系并在不修改业务代码的前提下随时切换监控后端。赞分享后端Web框架微服务RPC框架异步编程【免费下载链接】hyperf A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease.项目地址https://gitcode.com/hyperf/hyperf点击查看免费下载相关推荐Hyperf Metric 组件实战指南为微服务接入 Prometheus / StatsD / InfluxDB 监控体系Hyperf Metric 组件实战指南为微服务接入 Prometheus / StatsD / InfluxDB 监控体系 服务可观测性是微服务治理的核心需后端微服务Hyperf 服务监控组件实战基于 Prometheus / StatsD / InfluxDB 的可观测性接入指南Hyperf 服务监控组件实战基于 Prometheus / StatsD / InfluxDB 的可观测性接入指南 服务可观测性是微服务治理的核心诉求之一后端Web框架微服务RPC框架异步编程envelop/statsd 插件指南为 GraphQL 服务接入 StatsD 指标采集envelop/statsd 插件指南为 GraphQL 服务接入 StatsD 指标采集 本篇指南围绕 Envelop 插件体系中的 envelop/s后端API设计上一篇颠覆性GitHub效率革命让中文开发者告别语言障碍的界面汉化解决方案下一篇解决GitHub英文界面痛点用GitHub汉化插件实现98%界面精准转换创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表