Hyperf 多数据库监控需手动注入连接名标签并结合 mysqld_exporter 原生指标:必须为 db_query_duration_seconds 等指标添加 connection/type/table 标签,封装 Query Builder 或模型事件统一埋点,并为各 MySQL 实例部署独立 mysqld_exporter 以实现分库性能关联分析。

Hyperf 多数据库连接本身不自动上报各库的独立性能指标,监控需结合框架层埋点与数据库原生指标采集——不能只靠 hyperf_db_query_duration_ms,它不区分连接名,也无法反映连接池排队、跨库负载不均等问题。
明确各连接名对应的监控维度
Hyperf 的 Db::connection('log_db') 或模型 $connection = 'report_db' 是运行时逻辑,但默认 metric 不携带连接名标签。要实现分库统计,必须手动注入连接标识:
- 所有 DB 操作前,用
MetricFactoryInterface创建带 label 的 counter/histogram,例如:db_query_duration_seconds{connection="log_db",type="select"} - 避免全局复用同一指标名,否则 Prometheus 无法按连接名聚合分析
- 推荐 label 组合:
connection(必填)、type(select/update/insert)、table(可选,需业务层提取)
在 Query Builder 或模型方法中统一埋点
不建议每个 DAO 方法都手写指标,应封装成可复用的拦截或装饰逻辑:
- 对
Db::connection($name)返回的 query builder 实例做包装,重写select()、insert()等方法,在执行前后记录耗时和计数 - Eloquent 模型可通过 trait 注入,例如定义
TrackedConnection,在boot()中监听retrieving、saving等事件,自动打点 - 关键字段如
connection可从$this->getConnection()->getName()获取,无需硬编码
关联 mysqld_exporter 原生指标做交叉验证
仅靠 PHP 层埋点会遗漏底层瓶颈,必须把 Hyperf 的分库调用和 MySQL 实例状态打通:
- 为每个数据库实例部署独立的
mysqld_exporter,并用不同job_name标识,例如job_name: "mysql-log-db" - Prometheus 抓取配置中,通过
static_configs或file_sd_configs区分不同库的 exporter 地址 - Grafana 面板中,用 PromQL 关联查询:比如对比
rate(hyperf_db_query_duration_seconds_sum{connection="log_db"}[5m])和mysql_global_status_threads_connected{job="mysql-log-db"},判断是否因连接数上涨导致延迟升高
避免常见陷阱
多库监控最容易出错的地方不是代码,而是指标语义和采集链路:
- 不要复用同一个 counter 名称(如
db_queries_total)而不加connectionlabel,否则 Grafana 无法拆分图表 - Hyperf 的
enable_default_metric开启后,hyperf_db_query_duration_ms是全量统计,不含连接名,不能替代自定义埋点 - 如果使用连接池,注意
max_connections配置是 per-connection-name 的,需在 Prometheus 中分别看各库的hyperf_pool_connections_used指标


















