Hyperf MySQL断线重连靠连接池主动健康管理而非被动重试,需配准wait_timeout、max_idle_time(设为前者减30)、heartbeat(设为前者一半),min_connections≥2,心跳用PING而非SELECT 1,异常时协程安全重试≤3次。

Hyperf 的 MySQL 断线自动重连不是靠“断了再连”这种被动补救,而是通过连接池的主动健康管理和参数协同来规避失效连接,让每次取用都大概率拿到可用连接。关键在于配置对、机制清、不依赖异常后重试。
配准三个核心时间参数
MySQL 服务端有 wait_timeout(空闲连接被强制关闭的时间),Hyperf 连接池必须在这个时间点之前完成清理和探测:
- 先查真实值:
SHOW VARIABLES LIKE 'wait_timeout';(生产环境常见 300 或 600 秒) -
max_idle_time 必须严格小于它,建议设为
wait_timeout - 30(如 300 → 270) -
heartbeat 填具体秒数(不能写
true),推荐设为max_idle_time / 2(如 270 → 135),这是后台空闲检查线程的探测间隔
避免冷启动和连接枯竭
min_connections 别设为 0,否则首次请求要临时建连,延迟高且易在流量突增时争抢失败:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 建议设为 ≥ 2,保证服务启动后池中始终有活跃连接待用
- 配合
max_connections合理预估并发量(Swow 模式下注意check_interval ≥ 3000ms)
心跳检测要用 PING,不是 SELECT 1
Hyperf 默认用 PING 探活,轻量高效:
- 确认驱动支持:调用
DB::connection()->getPdo()->ping()不抛异常即可 - 不要手动改成
SELECT 1—— 它走完整 SQL 流程,开销大 3–5 倍,还可能因权限或上下文报错 - 若驱动极老旧不支持 PING,再退而配置
'checker' => 'SELECT 1',但需确保该语句在所有库都合法
重试逻辑只作兜底,不替代预防
当真遇到连接异常(如错误码 2006、2013),可封装协程安全的重试:
- 用
DB::transaction()包裹业务逻辑,不要在里面手动beginTransaction() - 捕获特定 PDO 异常,搭配指数退避(如
co::sleep(0.1 * ($i + 1))) - 重试上限建议 ≤ 3 次,避免雪崩;最后一次仍失败就原样抛出










