PHP常驻进程如何解决数据库连接被断开

50 篇文章 2 订阅

常驻进程的数据库连接是启动时初始化的,然后就一直连着,MySQL 的配置中,有一个叫做 “wait_timeout"的参数,这个参数大致的意思是这样:当一个客户端连接到 MySQL 数据库后,如果客户端不自己断开,也不做任何操作,MySQL 数据库会将这个连接保留"wait_timeout” 这么长时间(单位是 s,默认是 28800s,也就是 8 小时),超过这个时间之后,MySQL 数据库为了节省资源,就会在数据库端断开这个连接;当然,在此过程中,如果客户端在这个连接上有任意的操作,MySQL 数据库都会重新开始计算这个时间。
所以,需要自己实现重连机制来确保程序继续进行。

我们以Laravel为例,它已经实现了自动重连的机制。
vendor\Illuminate\Database\Connection.php中的run方法是最终执行sql的方法。

// 采用异常捕获的方式判断是否需要重连
protected function run($query, $bindings, Closure $callback)
{
    $this->reconnectIfMissingConnection();

    $start = microtime(true);

    // Here we will run this query. If an exception occurs we'll determine if it was
    // caused by a connection that has been lost. If that is the cause, we'll try
    // to re-establish connection and re-run the query with a fresh connection.
    try {
        $result = $this->runQueryCallback($query, $bindings, $callback);
    } catch (QueryException $e) {
        $result = $this->handleQueryException(
            $e, $query, $bindings, $callback
        );
    }

    // Once we have run the query we will calculate the time that it took to run and
    // then log the query, bindings, and execution time so we will report them on
    // the event that the developer needs them. We'll log time in milliseconds.
    $this->logQuery(
        $query, $bindings, $this->getElapsedTime($start)
    );

    return $result;
}
// 判断传入的数据库连接是否有效
protected function reconnectIfMissingConnection()
{
    if (is_null($this->pdo)) {
        $this->reconnect();
    }
}
// 重连
public function reconnect()
{
    if (is_callable($this->reconnector)) {
        return call_user_func($this->reconnector, $this);
    }

    throw new LogicException('Lost connection and no reconnector available.');
}

// 判断是连接断开导致的异常
// vendor\Illuminate\Database\DetectsLostConnections.php

protected function causedByLostConnection(Throwable $e)
{
    $message = $e->getMessage();

    return Str::contains($message, [
        'server has gone away',
        'no connection to the server',
        'Lost connection',
        'is dead or not enabled',
        'Error while sending',
        'decryption failed or bad record mac',
        'server closed the connection unexpectedly',
        'SSL connection has been closed unexpectedly',
        'Error writing data to the connection',
        'Resource deadlock avoided',
        'Transaction() on null',
        'child connection forced to terminate due to client_idle_limit',
        'query_wait_timeout',
        'reset by peer',
        'Physical connection is not usable',
        'TCP Provider: Error code 0x68',
        'Name or service not known',
        'ORA-03114',
    ]);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值