文章目录
概要
前段时间,公司的fastadmin项目要加入会员升级功能,我想可以把这些繁琐的升级判断做出守护进程,相当于丢到子线程中慢慢消化,肯定会提升代码执行效率。但完善了守护进程后,发现上线几天后,守护进程c操作了数据库,就开始报异常:SQLSTATE[HY000]: General error: 2006 MySQL server has gone away,一看这个错就是数据库连接出了问题。
技术细节
在fastadmin或者TP中,操作数据库一般用两种方式,一种是建model类,然后通过model对象操作数据库,还有一种方便快捷的方式,就是基于Db::name('table_name')的方式操作数据库,如果守护进程中这两种方式都涉及了,那么需要区分解决:
基于model类:
在database.php中加 :
php
'break_reconnect' => true,
📌 含义:
SQL 执行失败时,自动重连一次再执行
如果用Db::name的方式,可以在守护进程方法开始前,先运行一段代码:
php
try {
Db::query("SELECT 1");
} catch (\Exception $e) {
Db::clear();
}
实际作用是:
主动探测数据库连接是否还活着
SELECT 1 是最轻量的心跳 SQL
如果抛异常(比如 MySQL server has gone away)
说明当前 PDO 连接已经是 死连接
Db::clear()
清空 ThinkPHP 当前进程里缓存的连接
下一次 SQL 会 重新建连接
👉 在 常驻进程 / 长时间脚本 中,这是一个非常必要的防御手段。