hyperf中数据库连接数可通过db::connection()->getpool()->getstats()直接获取活跃/空闲/等待数,而redis连接数需依赖redis_exporter抓取服务端redis_connected_clients指标,二者因抽象层级不同不可统一计算。

Hyperf 中数据库和 Redis 的连接数获取方式完全不同,因为它们底层机制、监控粒度和暴露路径差异很大。不能用同一套逻辑去“查”或“算”,必须分开处理。
数据库连接数:看连接池实时状态
Hyperf 的 MySQL 连接池(尤其是启用 Swow 后)提供运行时接口,可直接读取当前活跃/空闲连接数:
- 通过 Db::getConnection() 获取当前使用的连接实例,再调用 getPool()->getStats(),返回数组含
active(已借出)、idle(空闲)、waiting(等待获取连接的协程数)等字段 - 注意:该统计仅针对当前连接名(如
default),多库需分别调用,例如Db::connection('log_db')->getPool()->getStats() - Swow 环境下必须确保已按规范重配
pool参数,否则getStats()返回的是兼容层伪值,不反映真实连接生命周期
Redis 连接数:依赖客户端驱动与外部指标
Hyperf 自身不暴露 Redis 连接池的实时连接计数,也没有内置方法返回 active_connections 这类数值:
-
hyperf/redis v3.2.5+ 启用 SwowHandler 后,连接由 Swow 的协程 TCP 管理,但未导出连接池统计接口;你无法像 Db 那样调用
$redis->getPool()->getStats() - 实际连接数只能间接估算:并发请求数 × 每请求平均使用连接时长 ÷ 平均空闲回收时间,但这只是理论模型,不精确
- 生产环境建议通过 redis_exporter + Prometheus 抓取 Redis 实例的
redis_connected_clients指标——这是 Redis 服务端维护的真实 TCP 连接数,包括来自 Hyperf 和其他客户端的全部连接
为什么不能统一对比?关键区别在这里
根本原因在于抽象层级不同:
- 数据库连接池是 Hyperf 在应用层完全托管的资源池,有明确的借还逻辑和状态跟踪
- Redis 客户端在 Swow 下复用的是底层协程 socket,连接生命周期由 Swow 内核管理,Hyperf 的 Redis 组件只负责命令分发,不维护连接计数
- Redis 的
connected_clients是服务端视角,而数据库getStats()是客户端池视角,二者单位和语义不一致,强行对比容易误导容量规划
实用建议:监控组合用法
想掌握真实负载,应结合两类数据源:
- 数据库侧:定时采集
Db::connection()->getPool()->getStats(),重点关注waiting > 0或idle === 0 && active === max_connections,表示池已饱和 - Redis 侧:配置
redis_exporter抓取redis_connected_clients和redis_blocked_clients,配合 Hyperf 应用 QPS(http_requests_total)做归因分析 - 压测时同步看两者:若 DB
waiting高而 Redisconnected_clients稳定,说明瓶颈在数据库;反之若 Redis 连接数飙升且出现EMFILE,大概率是 Redis 客户端未启用 SwowHandler 或max_connections设过低











