本质是连接池复用已被MySQL主动关闭的“僵尸连接”,需同步调大wait_timeout(建议1800秒)、配置heartbeat=true与max_idle_time=1740000毫秒,并确认启用Swow驱动及规范事务与连接释放。

Hyperf 3.1 报 MySQL server has gone away 或 Lost connection to MySQL server,本质不是数据库挂了,而是连接池把已被 MySQL 主动关闭的“僵尸连接”又发给了业务代码——程序拿着一个失效的 socket 去执行 SQL,自然报错。
检查 MySQL 的 wait_timeout 是否过短
这是最常见诱因。Hyperf 连接池里的连接如果空闲时间 ≥ MySQL 的 wait_timeout,服务端就会断开它,但连接池不知道,下次还可能把它复用出去。
- 登录 MySQL 执行:
SHOW VARIABLES LIKE 'wait_timeout';,典型值可能是 300(5 分钟)、600(10 分钟)或默认 28800(8 小时) - 务必同步查
interactive_timeout,它和wait_timeout通常需设为相同值,否则部分客户端行为不一致 - 若值太小(如 ≤ 300),建议调大到 1800(30 分钟)或 3600(1 小时),避免频繁中断
配置 heartbeat + max_idle_time 协同生效
Hyperf 不会自动探测连接是否还活着,必须靠心跳机制在连接归还前做一次轻量验证(如 SELECT 1)。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 在
config/autoload/databases.php对应数据库配置的pool下添加: -
'heartbeat' => true:必须开启,否则心跳不触发 -
'max_idle_time' => 1740000:单位毫秒,建议比 MySQL 的wait_timeout(秒)少 60 秒,例如 MySQL 设为 1800 秒 → 此处填1740000(即 1740 秒) -
'min_connections' => 1:可选,防止全空闲时连接池清零,提升冷启动响应
确认 Swow 或 Swoole 驱动适配正确
Hyperf 3.1 默认支持 Swow,但旧配置容易残留导致连接管理失效。
- 运行
php bin/hyperf.php start后,看控制台是否输出Swow\Coroutine\MySQL;若显示Swoole\Coroutine\MySQL,说明未启用 Swow - 启用 Swow 需确保:
config/autoload/server.php中'mode' => SWOW_BASE,且 PHP 扩展已加载 Swow(非 Swoole) - Swow 环境下,
pool配置必须用全新结构(不能沿用 Swoole 时代的旧 pool 键),否则参数被忽略
堵住连接泄漏与上下文污染
即使心跳开启,若连接被长期独占不释放,也会堆积大量 Sleep 连接,最终挤占有效连接资源。
- 事务必须用
DB::transaction()包裹,禁用原生$connection->beginTransaction(),否则协程切换后连接状态错乱 - Redis pipeline / MySQL 批量操作,必须确保
->exec()执行;异常分支里加finally { $pipe->exec(); } - 避免在协程中混用 PDO 原生调用,只走 Hyperf\Database\Connection 或 Eloquent,防止句柄复用冲突
- 定时任务(如
Hyperf\Crontab)每次执行完应主动清理连接,可在任务结尾加DB::disconnect();

















