PHP 套接字服务器中的数据库连接
DB Connection in PHP Socket Server
我是 运行 一个启动 websocket 聊天服务的 Yii2 控制台应用程序。一切正常,正如预期的那样,但在一段时间不活动后,我得到 SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
。我尝试增加超时,将用户中止设置为 false 并在 PDO
的构造函数中设置 PDO::ATTR_PERSISTENT => true
,但这仍然在发生。
有没有办法检查数据库连接是否仍然处于活动状态,或者如果不是,如何重新连接到数据库。纯 php 或更好的 Yii2 框架。
不确定该代码的确切位置,但是可以使用 yii\db\Connection
class 中的方法检查连接是否活动的相关代码
getIsActive()
: Returns a value indicating whether the DB connection
is established.
要重新连接,您可以使用
open()
: Establishes a DB connection. It does nothing if a DB
connection has already been established.
if(Yii::$app->db->isActive === FALSE){
Yii::$app->db->open();
}
我遇到了类似的问题,并通过为数据库连接创建自己的 class 解决了这个问题,这确保了在实际查询之前连接处于活动状态。
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 隐式回滚,并且上面的代码将隐式重新连接,因此您甚至不会注意到您的事务在某些时候被回滚点.
我也没有在主从配置下测试它。但它在我的情况下工作得很好(只读连接到单个服务器),所以你可以将它用作基础并通过额外检查事务或 master/slave 连接来调整你的需要。
我是 运行 一个启动 websocket 聊天服务的 Yii2 控制台应用程序。一切正常,正如预期的那样,但在一段时间不活动后,我得到 SQLSTATE[HY000]: General error: 2006 MySQL server has gone away
。我尝试增加超时,将用户中止设置为 false 并在 PDO
的构造函数中设置 PDO::ATTR_PERSISTENT => true
,但这仍然在发生。
有没有办法检查数据库连接是否仍然处于活动状态,或者如果不是,如何重新连接到数据库。纯 php 或更好的 Yii2 框架。
不确定该代码的确切位置,但是可以使用 yii\db\Connection
class 中的方法检查连接是否活动的相关代码
getIsActive()
: Returns a value indicating whether the DB connection is established.
要重新连接,您可以使用
open()
: Establishes a DB connection. It does nothing if a DB connection has already been established.
if(Yii::$app->db->isActive === FALSE){
Yii::$app->db->open();
}
我遇到了类似的问题,并通过为数据库连接创建自己的 class 解决了这个问题,这确保了在实际查询之前连接处于活动状态。
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 隐式回滚,并且上面的代码将隐式重新连接,因此您甚至不会注意到您的事务在某些时候被回滚点.
我也没有在主从配置下测试它。但它在我的情况下工作得很好(只读连接到单个服务器),所以你可以将它用作基础并通过额外检查事务或 master/slave 连接来调整你的需要。