账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    swoole 异步mysql连接池对象在数据库重启后重连时被拒绝如何解决?
    32
    0
    我用的框架: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. 111MySQL server has gone away. 2006然而,在mysql 停机期间没有去连接过mysql的对象 在 mysql启动后再次去连接是成功的。上面描述可能有点费解,我举个例子:我连接池有10个连接对象,mysql停机期间有4个尝试连接了(肯定是失败的),mysql启动后,其它6个对象可以正常重连,这4个对象再也连不上了。发现这个问题,我都是费了很大的精力,也不知为啥 。请哪个大牛来给我解释一下?
    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • 扯线公仔 普通会员 1楼

      在Swoole中,如果MySQL连接池对象在数据库重启后被拒绝,可能是由于以下原因:

      1. 连接池未正确关闭:如果在数据库重启后没有正确关闭连接池,可能会导致新的连接请求被拒绝。

      2. 数据库连接问题:如果数据库连接有问题,例如连接超时、数据库连接被关闭等,也可能导致新的连接请求被拒绝。

      3. PHP代码问题:如果PHP代码中存在错误,例如SQL语句错误、错误的错误处理等,也可能导致新的连接请求被拒绝。

      4. 异步数据库连接超时:如果在异步数据库连接超时后没有重新连接,也可能导致新的连接请求被拒绝。

      要解决这个问题,可以尝试以下方法:

      1. 在数据库重启后,检查连接池是否正确关闭。如果需要,可以手动关闭连接池。

      2. 检查数据库连接问题。例如,可以检查数据库连接超时时间、数据库连接是否被关闭等。

      3. 检查PHP代码问题。例如,可以检查SQL语句、错误处理等。

      4. 如果需要,可以增加异步数据库连接超时时间。

      5. 如果问题仍然存在,可以考虑增加连接池的大小,以增加连接的容量。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部