easyswoole数据库连接池_【转】swoole mysql连接池之断线重连

本文探讨了如何增强Swoole MySQL连接池的健壮性,通过错误检测和断线重连机制,确保在异常情况下仍能稳定运行。介绍了在长时间无操作、MySQL重启或更改数据库设置时,如何处理连接失效,并展示了通过`__call`方法实现的断线重连和异常处理代码示例。
摘要由CSDN通过智能技术生成

怎么理解健壮?

当程序任何一个环节出现故障或异常,都能有稳定的预期或输出

为什么说之前连接池不够健壮呢?

你可以尝试以下几个操作, 然后访问 http://127.0.0.1:9501/list:

长时间不操作,

重启下mysql

修改下数据库或者表名

得出的结果都是 false,  这里就完全不在我们预期之内,那开始我们的优化之路吧

第一步:false变异常

当返回false时,我们可以通过$mysql的相关属性来获取相关的错误信息

$result = $mysql->query("select * from test");

if(false == $result) {

var_dump($result);

}

可以得到如下信息:

// ["sock"]=> int(8)

// ["connected"]=> bool(false)

// ["connect_error"]=> string(24) "connection close by peer"

// ["connect_errno"]=> int(111)

// ["affected_rows"]=> int(0)

// ["insert_id"]=> int(0)

// ["error"]=> string(26) "MySQL server has gone away"

// ["errno"]=> int(2006)

// ["errCode"]=> int(5001)

进一步改造:

$result = $mysql->query("select * from test");

if(false == $result) {

throw new RuntimeException($mysql->error, $mysql->errno);

}

这样我们就可以捕获异常,进行相关的逻辑处理

但这样每次都在业务层去做判断不是很好的实现方式,可以抽出一个中间层,然后简单改造一下mysql_pool,代码如下:

use Swoole\Coroutine\MySQL;

class mydb

{

/**

* @var MySQL

*/

private $mysql;

private $config;

/**

* @param $config

* @return mixed

* @desc 连接mysql

*/

public function connect($config)

{

$mysql = new MySQL();

$res = $mysql->connect($config);

if ($res == false) {

//连接失败,抛弃常

throw new RuntimeException($mysql->connect_error, $mysql->errno);

} else {

//mysql连接存入channel

$this->mysql = $mysql;

$this->config = $config;

}

return $res;

}

/**

* @param $name

* @param $arguments

* @return mixed

* @desc 利用__call,实现操作mysql,并能做断线重连等相关检测

*/

public function __call($name, $arguments)

{

$result = call_user_func_array([$this->mysql, $name], $arguments);

if (false === $result) {

if (!empty($this->mysql->errno)) { //有错误码,则抛出弃常

throw new RuntimeException($this->mysql->error, $this->mysql->errno);

}

}

return $result;

}

}

保存为mydb.php, 这里我们利用到__call方法,然后可以在操作mysql进行前后置的判断,统一做一些处理

在mysql_pool.php文件里引入:

require_once "mydb.php";

然后把

$mysql = new MySQL();

改成

$mysql = new mydb();

第二步:断线重连

上面我们看到了一个经典的错误:MySQL server has gone away,他是如何产生的呢?

长时间未操作,mysql会主动关闭空闲的连接,防止占着茅坑不拉屎的行为, 时间由 wait_timeout 配置决定,可通过 show variables like “%timeout%”查看配置的时间是多少?

mysql重启后,所以的旧连接自然就失效了

所以当出现了这些情况,我们还拿着旧的连接去操作,当然就报错了,但碰到这个错误,我们直接抛异常也不太合理,因为我们可以通过断线重连的机制,重新建立一个新的连接,实现也非常简单,看代码:

/**

* @param $name

* @param $arguments

* @return mixed

* @desc 利用__call,实现操作mysql,并能做断线重连等相关检测

*/

public function __call($name, $arguments)

{

$result = call_user_func_array([$this->mysql, $name], $arguments);

if (false === $result) {

if (!$this->mysql->connected) { //断线重连

$this->connect($this->config);

return call_user_func_array([$this->mysql, $name], $arguments);

}

if (!empty($this->mysql->errno)) { //有错误码,则抛出弃常

throw new RuntimeException($this->mysql->error, $this->mysql->errno);

}

}

return $result;

}

如果我们发现是连接失效,我们再尝试新建连接即可,其他的错误,按异常处理

至此,我们一个健壮的mysql连接池就有了,是不是很简单呢。

抛个问题?

为什么mysql要主动关闭长久不活跃的连接?像redis就没有这样的机制

预告:

下一篇我们将继续扩展连接池,使之可以支持主从模式

查看原文,可以详细了解swoole的mysql有哪些属性

原文链接:https://mp.weixin.qq.com/s/txKoxedoJjnLnPDq7VBMhg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值