今天在咱们EasySwool的交流群里发现有些小伙伴对于MySQL连接的基本情况处理不够重视,直到出现MySQL报出的异常,才在群里问,每次MySQL运行了一段时间后,就会出现这个错误,这是什么情况怎么处理

错误例如 :

SQLSTATE[HY000]: General error: 2006 MySQL server has gone away

这种情况分析就是:

1、运行一段时间后出现,重启服务后正常,又重复。明确是 连接超时,会话被关闭。

处理办法

修改MySQL配置

MySQL相关配置的解读在我另外一篇文章有写

设置合适的timeout,分别是2个配置:

[mysqld]
wait_timeout = 604800
#等待超时时间 默认 8小时
interactive_timeout = 604800
#关闭连接之前,允许 interactive_timeout(取代了wait_timeout)秒的不活动时间。客户端的会话 wait_timeout 变量被设为会话interactive_timeout 变量的值。如果前端程序采用短连接,建议缩短这2个值, 如果前端程序采用长连接,可直接注释掉这两个选项,或者加长时间 默认配置(8小时)  

在EasySwoole框架中

1、在ORM组件中使用连接池,高效管理MySql连接, EasySwoole\ORM\Db\Connection 实现了连接池的使用

use EasySwoole\ORM\DbManager;
use EasySwoole\ORM\Db\Connection;
use EasySwoole\ORM\Db\Config;

public static function initialize()
{
    $config = new Config();
    $config->setDatabase('easyswoole_orm');
    $config->setUser('root');
    $config->setPassword('');
    $config->setHost('127.0.0.1');
    $config->setTimeout(15); // 超时时间
    //连接池配置
    $config->setGetObjectTimeout(3.0); //设置获取连接池对象超时时间
    $config->setIntervalCheckTime(30*1000); //设置检测连接存活执行回收和创建的周期
    $config->setMaxIdleTime(15); //连接池对象最大闲置时间(秒)
    $config->setMinObjectNum(5); //设置最小连接池存在连接对象数量
    $config->setMaxObjectNum(20); //设置最大连接池存在连接对象数量
    $config->setAutoPing(5); //设置自动ping客户端链接的间隔

    DbManager::getInstance()->addConnection(new Connection($config));
}

我们要注意几个配置:

setIntervalCheckTime
setMaxIdleTime
setAutoPing

IntervalCheckTime 配置项,它指定的就是多久做一次周期检查
MaxIdleTime 配置项指的是如果一个连接超过这个时间没有使用,则会被回收。
AutoPing 配置项指的是多久执行一个 select 1 用来触发这个连接,让这个连接被 mysql 服务端标记为活跃而不会被回收。
如果经常出现断线,可以适当缩短 周期性检查 和 AutoPing 的时间(即调整 IntervalCheckTimeAutoPing 配置项的值)。

理论上,以上配置之后断线概率已经是非常低的了。

最后还是建议,在任何数据库io操作中,一定要使用 try - catch 例如:

<?php
try {
    $client = $pool->getClient();
    $cilient->query(xxxxxx);
} catch (\Throwable $t) {}