webman中mysql断连不自动重连,因illuminate/database的pdo驱动无保活机制;须改用swoole\coroutine\mysql实现自动重建,或在pdo场景下通过try-catch捕获2006/2013错误并手动重试,同时配合连接池、心跳检测及mysql端wait_timeout调优。

Webman里MySQL连接断开后不会自动重连
Webman 默认使用的 illuminate/database 是同步 PDO 驱动,它本身不带连接保活或自动重连逻辑。一旦 MySQL 服务重启、网络闪断或 wait_timeout 超时(默认8小时),下次查询就会抛出 SQLSTATE[HY000]: General error: 2006 MySQL server has gone away —— 这不是配置没生效,而是底层根本没做重连动作。
用 Swoole 协程 MySQL 客户端替代 PDO
这是最直接有效的方案:换掉默认驱动,用 Swoole\Coroutine\Mysql,它在协程环境下天然支持连接复用和失败后自动重建连接。
- 不要在控制器里 new
Swoole\Coroutine\Mysql,每次请求都新建实例会浪费资源;应在onWorkerStart中初始化并存入全局变量或容器 - 连接配置必须包含
timeout字段(单位秒),建议设为 5~10,否则 query 阻塞会拖垮整个协程 -
query()返回数组而非 PDOStatement,不能用fetch(),直接遍历结果即可 - 若需事务控制,必须手动调用
begin()/commit()/rollback(),协程 MySQL 不支持自动事务上下文
PDO 场景下靠 try-catch + 手动重试兜底
如果你无法切换驱动(比如依赖 Eloquent 的部分特性),只能靠代码层补救。但注意:这不是“自动重连”,而是“失败后重试一次”。
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
- 捕获
PDOException时,检查错误码是否为2006或2013(Lost connection) - 调用
Db::reconnect()(仅 webman/database 插件提供)或手动Db::purge()+Db::connection()->getPdo()触发重建 - 重试逻辑必须包裹在事务外——已开启的事务在连接断开后必然失效,强行 commit 会报错
- 别在模型的
boot()或中间件里全局挂重试,容易掩盖真实问题,且高并发下可能重复执行业务逻辑
连接池和心跳是长期运行服务的刚需
独立进程(如定时任务、消息消费者)比 HTTP 请求更易暴露连接老化问题。光靠重试不够,得从连接生命周期入手。
- 使用
webman/mysql插件时,务必配置max_idle_time(如 60 秒)和max_active(如 20),让空闲连接及时释放 - 在
onWorkerStart启动一个协程定时器,每 30 秒执行一次PING查询(SELECT 1),保持连接活跃 - MySQL 侧要调大
wait_timeout和interactive_timeout(建议 300~600),避免服务端主动断连 - 别把数据库连接当普通对象反复 new —— 协程环境里每个连接句柄都是独占资源,泄漏会快速耗尽 MySQL 最大连接数
真正麻烦的不是第一次断连,而是连接池里混入了已失效但未清理的句柄。这类问题在线上跑几天才暴露,日志里只有一堆 2006 错误,查不到源头。所以初始化时机、连接复用边界、空闲回收策略,三者缺一不可。










