我用的框架:SwooleDistributed 3, swoole 4.1, PHP7.1
这个框架是有mysql异步连接池的,按他的源码,连接池对象在失去连接后会重连的,一般没问题。
重连代码如下:
public function query($sql, $client = null, MySqlCoroutine $mysqlCoroutine)
{
$notPush = false;
$delayRecv = $mysqlCoroutine->getDelayRecv();
if ($client == null) {
$client = $this->pool_chan->pop();
$client->setDefer($delayRecv);
} else {//这里代表是事务
$notPush = true;
//事务不允许setDefer
$delayRecv = false;
$client->setDefer($delayRecv);
}
if (!$client->connected) {
$set = $this->config['mysql'][$this->active];
//(重点在这里,注释掉的是我调试的)
//echo "\n\n";
//print_r($client);
//$client->close();
$result = $client->connect($set);
//ar_dump($result);
if (!$result) {
$this->pushToPool($client);
$errcode = $client->errno ?? '';
$mysqlCoroutine->getResult(new SwooleException(sprintf("[%s]%s,%s", $errcode, $client->connect_error ??'' , $client->error ?? '')));
}
}
$res = $client->query($sql, $mysqlCoroutine->getTimeout() / 1000);
if ($res === false) {
$this->pushToPool($client);
if ($client->errno == 110) {
$mysqlCoroutine->onTimeOut();
} else {
$mysqlCoroutine->getResult(new SwooleException("[sql]:$sql,[err]:$client->error"));
}
}
$mysqlCoroutine->destroy();
if ($delayRecv)//延迟收包
{
$data['delay_recv_fuc'] = function () use ($client) {
$res = $client->recv();
$data['result'] = $res;
$data['affected_rows'] = $client->affected_rows;
$data['insert_id'] = $client->insert_id;
$data['client_id'] = $client->id;
$this->pushToPool($client);
return $data;
};
return new MysqlSyncHelp($sql, $data);
}
$data['result'] = $res;
$data['affected_rows'] = $client->affected_rows;
$data['insert_id'] = $client->insert_id;
$data['client_id'] = $client->id;
if (!$notPush) {
$this->pushToPool($client);
}
return new MysqlSyncHelp($sql, $data);
}
运维要半夜维护mysql,是需要停机的,过一小段间后再启动。于是我们业务代码,也就是连接池里的对象,在他停机期间连接了mysql,很明显会失败.
问题来了:我进程内的连接池里有10个swoole异步连接对象,这些连接对象在mysql 停机期间去连接过mysql的,在mysql启动后再次去连接时就报了如下的错:
Connection refused. 111
MySQL server has gone away. 2006
然而,在mysql 停机期间没有去连接过mysql的对象 在 mysql启动后再次去连接是成功的。
上面描述可能有点费解,我举个例子:
我连接池有10个连接对象,mysql停机期间有4个尝试连接了(肯定是失败的),mysql启动后,其它6个对象可以正常重连,这4个对象再也连不上了。
发现这个问题,我都是费了很大的精力,也不知为啥 。
请哪个大牛来给我解释一下?