首页
下载
文档
社区
视频
捐赠
源代码
赞助商
AOT 编译器
AI 助理
商业产品
PHP AOT 原生编译器
Swoole-Compiler 代码加密器
CRMEB 新零售社交电商系统
登录
注册
全部
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
发表新帖
SwooleDistributed 3 mysql连接池在数据库重启后全部失效,然后重连时报2006 Connection refused错误怎么解决?
### 问题描述 说来就蛋疼了,这个SwooleDistributed 3的框架在我开发项目之前就已经停止更新了,上面让用这个框架开发这个项目。现在的问题是我的mysql连接是使用了官方说的异步连接池进行的,然后数据库重启后,连接池全挂。可以看到底层逻辑是会进行重连的,但是报如 Connection refused 2006 的数据库连接错误,请问大神们这到底是mysql的问题,还是框架程序的问题? ### Swoole版本,PHP版本,以及操作系统版本信息 运行是用docker 容器,镜像是 lenkaren/php-swoole:latest 进入镜像看到的信息是: "PHP_VERSION=7.1.14", "SWOOLE_VERSION=4.1.2", ### 相关代码 ```php /** * @param $sql * @param null $client * @param MySqlCoroutine $mysqlCoroutine * @return mixed * @throws \Throwable */ 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]; $result = $client->connect($set); if (!$result) { $this->pushToPool($client); $errcode = $client->errno ?? ''; //接下来就报错 $mysqlCoroutine->getResult(new SwooleException(sprintf("err:%s,code:%s", $client->connect_error, $errcode))); } } $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); } ``` ### 你期待的结果是什么?实际看到的错误信息又是什么?
发布于4年前 · 17 次浏览 · 来自
提问
学渣
### 问题描述 说来就蛋疼了,这个SwooleDistributed 3的框架在我开发项目之前就已经停止更新了,上面让用这个框架开发这个项目。现在的问题是我的mysql连接是使用了官方说的异步连接池进行的,然后数据库重启后,连接池全挂。可以看到底层逻辑是会进行重连的,但是报如 Connection refused 2006 的数据库连接错误,请问大神们这到底是mysql的问题,还是框架程序的问题? ### Swoole版本,PHP版本,以及操作系统版本信息 运行是用docker 容器,镜像是 lenkaren/php-swoole:latest 进入镜像看到的信息是: "PHP_VERSION=7.1.14", "SWOOLE_VERSION=4.1.2", ### 相关代码 ```php /** * @param $sql * @param null $client * @param MySqlCoroutine $mysqlCoroutine * @return mixed * @throws \Throwable */ 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]; $result = $client->connect($set); if (!$result) { $this->pushToPool($client); $errcode = $client->errno ?? ''; //接下来就报错 $mysqlCoroutine->getResult(new SwooleException(sprintf("err:%s,code:%s", $client->connect_error, $errcode))); } } $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); } ``` ### 你期待的结果是什么?实际看到的错误信息又是什么?
赞
0
收藏
提问
分享
讨论
建议
公告
开发框架
CodeGalaxy
登录
后参与评论
评论
2021-11-27
学渣
找了好多资料了,没解决,希望哪个大神来解决一下
赞
0
回复
2021-11-27
学渣
通过看这个框架的底层代码 ,是可以发现一个问题的,那个数据库连接对象 client ,连接失败时会重连,虽然配置信息去重连mysql,但是这个client是重启前的那个句柄,往网络层来说 就是 这个session是旧的,重启后的mysql不认可这个session所以 ,被mysql拒绝了。 这是我猜测,目前还没找到大牛给我确定,或解答这个问题。也许我需要把 client这个对象都销毁掉,新建一个\Swoole\Coroutine\MySQL() 对象对连接mysql。如果是这样的话,那这个问题就无解了,框架底层根本没实现这样的。
赞
0
回复
2021-12-01
学渣
在mysql 停机期间没有去连接过mysql的对象 在 mysql启动后再次去连接是成功的。 上面描述可能有点费解,我举个例子: 我连接池有10个连接对象,mysql停机期间有4个尝试连接了(肯定是失败的),mysql启动后,其它6个对象可以正常重连,这4个对象再也连不上了。 发现这个问题,我都是费了很大的精力,也不知为啥 。 请哪个大牛来给我解释一下?
赞
0
回复
2021-12-07
哪吒
看下laravel的连接 失败了 try cache一下、重新查询就好了 
赞
0
回复