hyperf高并发连接池优化核心是“够用、可控、可回收”:数据库池max_connections设80~100,min_connections设10~20,wait_timeout为2~3秒,max_idle_time为55秒;redis池按qps×调用次数×1.2计算并向下取整;grpc需固定大小轮询池,禁用单例和sync.pool;须配合监控告警与泄漏排查。

Hyperf 在高并发场景下优化连接池连接数,核心不是盲目调大数值,而是让连接数“够用、可控、可回收”。关键在于匹配业务峰值、规避协程逃逸、防止连接泄漏,并配合健康检查与监控闭环。
数据库连接池:按需设限,避免超 MySQL 承载
MySQL 默认 max_connections=151,生产环境必须预留运维通道(如 DBA 登录、备份任务),所以 Hyperf 数据库连接池的 max_connections 建议设为 80~100。同时注意:
- min_connections 设为 10~20:服务启动即预热,避免冷启动时大量建连阻塞请求
- wait_timeout 控制在 2~3 秒:连接池无空闲连接时快速失败,而非让请求长时间排队
-
max_idle_time 设为 55 秒(小于 MySQL 的
wait_timeout=60s):确保空闲连接在被 MySQL 主动断开前就主动释放 - 开启
heartbeat => -1,交由max_idle_time管理心跳,避免额外心跳干扰
Redis 连接池:必须配池,且 max_connections ≥ 并发预期 × 1.2
Redis 是高频访问组件,未配连接池会导致每请求新建 TCP 连接,迅速打满文件描述符。生产环境务必启用 hyperf/redis 并配置连接池:
- max_connections 不按 CPU 核数估算,而按压测或历史峰值 QPS × 平均每个请求 Redis 调用次数 × 1.2 得出
- 例如:QPS 峰值 2000,平均每次请求查 3 次 Redis → 建议
max_connections ≥ 2000 × 3 × 1.2 = 7200,再结合 Redis 实例规格向下取整(如单节点建议 ≤ 5000) - 禁用
lazy模式,确保连接在 Worker 启动时预热完成
gRPC 连接池:拒绝单例和 sync.Pool,改用固定大小轮询池
gRPC 连接数爆炸常源于误用 grpc.Dial 或 sync.Pool 缓存 *grpc.ClientConn —— 因连接带活跃网络状态,GC 不回收,池子越积越大。正确做法是:
- 定义固定大小连接池结构,
maxConnections显式设为 10~50(视后端 gRPC 服务吞吐能力而定) - 所有 gRPC client 必须复用同一组
*grpc.ClientConn实例,不能每个协程 new 一个 client - 连接创建加
WithBlock()+ 短超时(如 3 秒),避免初始化卡死阻塞整个池 - 池生命周期绑定 Worker:在
OnWorkerStart初始化,在OnWorkerStop遍历调用conn.Close()
通用监控与兜底:让连接数“看得见、控得住”
光靠配置不够,必须建立可观测性:
- 通过
PoolFactory::getPool('default')->getCurrentConnections()和getConnectionsInChannel()实时采集使用率 - 将连接池指标暴露为 Prometheus metrics,设置告警:当使用率持续 >90% 或空闲连接长期为 0,触发扩容或排查泄漏
- 定期检查慢查询、长事务、未关闭的 PDOStatement,这些都会导致连接被长期占用不归还
- 在异常中间件中捕获
ConnectionException,记录连接获取失败日志,辅助定位 wait_timeout 是否过短











