hyperf连接池必须显式控制max_connections、按服务维度隔离池实例、适配运行时环境;禁用自动伸缩与动态扩容,采用固定大小+预分配策略,避免误复用和连接泄漏。

Hyperf 连接池连接数分配策略不能靠“自动伸缩”或“按需创建”,必须显式控制上限、隔离使用场景、匹配运行时特征。核心不是调大数字,而是让每个连接池在正确的时间、被正确的协程、以正确的方式复用。
固定大小 + 预分配,禁用动态扩容
Hyperf 默认的 SimplePool 或基于 sync.Pool 的实现容易导致连接堆积或误复用。生产环境应放弃“最小连接数自动维持+最大连接数弹性扩容”的逻辑:
- 设置
max_connections为明确值(如 MySQL 建议设为 CPU 核数 × 2,4 核配 8;Redis 高频读写可设 50–100) - 关闭
min_connections自动预热(尤其双主、VIP 场景下,预热连接可能全落在失效节点) - 不依赖
wait_timeout触发扩容,而用固定池容量 + 轮询分发,避免连接数随请求峰谷剧烈波动
按服务维度隔离池实例
不同下游服务必须使用独立连接池,不能共用同一组连接对象:
- MySQL 主库、从库、日志库要分不同 pool(如
mysql_master、mysql_slave、mysql_log) - gRPC 多个服务端(user-service、order-service)不可共享
*grpc.ClientConn,每个应有专属池 - MongoDB 按数据库名隔离 —— 即使连接串不同,只要
database相同,就会混用连接,多租户场景极易错乱
适配运行时与网络环境
连接池参数要和 Swoole 协程生命周期、VPC 网络中间设备协同:
-
max_idle_time设为 ≤30 秒(双主 VIP 切换、K8s Pod 重建后,旧连接需快速淘汰) - 启用 TCP Keepalive(OS 层),不能只靠连接池的
heartbeat(协议层 PING) - 在
OnWorkerStart中初始化池,在OnWorkerStop中遍历Close()所有连接,避免协程逃逸导致连接泄漏 - VPC 内建议池大小设为
CPU 核数 × 2,避免跨 AZ 延迟放大
规避常见误用陷阱
很多连接数爆炸问题其实源于编码习惯而非配置本身:
- 禁止在 Controller 构造函数或方法内直接
new Client()或调用grpc.Dial()—— 每次 new 都可能建新连接 - 禁止对从池中取出的连接手动
Close()(如 Redis$pool->get()->close()),应交由池统一回收 - gRPC 客户端必须复用池返回的
*grpc.ClientConn,不能每个 client 实例持有自己的 conn - MySQL 双主场景禁用
ATTR_PERSISTENT(持久连接),否则失效连接会长期滞留











