首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

PHP CLI 長連程序 MySQL 閃斷自動重連實戰:PDO 連接池單例模式改造

     編輯:MySQL 資料庫相關知識

問題場景

PHP CLI 守護進程(如短信群發)長期運行,MySQL 重啟或網絡抖動導致「MySQL server has gone away」(錯誤 2006),單例模式下舊連接失效卻未重建,後續查詢全部失敗。

原始單例缺陷

if (isset(self::$_instance) && !empty(self::$_instance)) {
    return self::$_instance; // 閃斷後仍返回失效連接
}

改造方案:錯誤攔截 + 連接重置

class DB {
    private static $_instance = null;

    public static function get_conn($config) {
        if (isset(self::$_instance) && !empty(self::$_instance)) {
            return self::$_instance;
        }
        // ... 建立新 PDO 連接 ...
        self::$_instance = $conn;
        return $conn;
    }

    public static function query($dbconn, $sql, $params) {
        $sth = $dbconn->prepare($sql);
        try {
            $sth->execute($params);
        } catch (PDOException $e) {
            echo $e->getMessage() . PHP_EOL;
            self::reset_connect($e->getMessage()); // 關鍵:檢測閃斷並重置
        }
        return $sth->fetchAll(PDO::FETCH_ASSOC);
    }

    public static function reset_connect($err_msg) {
        if (strpos($err_msg, 'MySQL server has gone away') !== false) {
            self::$_instance = null; // 強制下次重建
        }
    }
}

驗證效果

# 模擬閃斷
mysql.server stop && mysql.server start

# 改造前:持續報錯 2006,空結果
# 改造後:當次失敗,下一次自動重連成功,業務繼續

生產環境建議

  • 結合 PDO::ATTR_PERSISTENT 謹慎使用(預連接池可能殘留失效連接)。
  • 擴展錯誤碼判斷:2006、2013(Lost connection)、HY000 通用錯誤。
  • 加入指數退避重試邏輯,避免高頻重連衝擊資料庫。
  • 考慮使用 Swoole/RoadRunner 等常駐框架,內建連接池與重連機制。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved