PHP套接字服务器中的数据库连接

时间:2018-04-29 16:23:48

标签: php database sockets yii2 long-running-processes

我正在运行一个启动websocket聊天服务的Yii2控制台应用程序。这一切都正常,正如它应该的那样,但经过一段时间的不活动后,我得到了SQLSTATE[HY000]: General error: 2006 MySQL server has gone away。我试图增加超时,将用户中止设置为false并在PDO::ATTR_PERSISTENT => true的构造函数中设置PDO,但这仍然在发生。

是否有办法检查数据库连接是否仍处于活动状态,或者是否如何重新连接到数据库。无论是纯PHP还是更好的Yii2框架。

2 个答案:

答案 0 :(得分:1)

我有一个类似的问题并通过创建我自己的数据库连接类来解决它,这可以确保在实际查询之前连接是活动的。

class DbConnection extends \yii\db\Connection {

    private $stamp;

    /**
     * {@inheritdoc}
     */
    public function createCommand($sql = null, $params = []) {
        try {
            // send ping on every 10 seconds
            if ($this->stamp < time()) {
                $this->stamp = time() + 10;
                parent::createCommand('SELECT 1')->execute();
            }
        } catch (\yii\db\Exception $e) {
            // if ping fail, reconnect
            $this->close();
            $this->open();
        }
        return parent::createCommand($query);
    }
}

每10秒钟一次,它会在创建命令之前发送“ping”查询。如果ping失败(连接中断),它会尝试重新连接。

这不会阻止断开连接,但如果连接中断,它将自动重新连接。如果您正在使用事务,这可能会很棘手 - 如果连接在事务中间中断,事务将由DB隐式回滚,并且上面的代码将隐式重新连接,因此您甚至不会注意到您的事务在某些事务中回滚点。

此外,我没有在主从配置中测试它。但它在我的情况下完全正常(只读连接到单个服务器),因此您可以使用它作为基础并通过额外的事务检查或主/从连接来调整您的需求。

答案 1 :(得分:0)

不确定您应该准确指出此代码的位置,但是可以使用yii\db\Connection类中的方法检查连接是否处于活动状态的相关代码

  

getIsActive():返回一个指示数据库连接的值   成立。

并重新连接,您可以使用

  

open():建立数据库连接。如果是DB,它什么都不做   联系已经建立。

if(Yii::$app->db->isActive === FALSE){
     Yii::$app->db->open();
}