首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP MySQL 長連接 mysql_pconnect 深度解析與避坑指南

     編輯:PHP 相關知識

長連接運作前提:Apache Keep-Alive

PHP 作為 Apache 模組運行時,長連接能否生效取決於 Apache 的 Keep-Alive 設定。

Keep-Alive 原理

  • 無 Keep-Alive:每次 HTTP 請求需建立/關閉 TCP 連線 (3 次交握 + 4 次揮手)
  • 啟用 Keep-Alive:單一 TCP 連線處理多個 HTTP 請求,大幅降低開銷

Apache 關鍵設定 (httpd.conf)

KeepAlive On
MaxKeepAliveRequests 0    # 不限制單連線請求數
KeepAliveTimeout 15       # 保持連線秒數,關鍵參數

驗證 Keep-Alive 生效

<?php
echo "Apache 進程 PID: " . getmypid();
// 15 秒內重整頁面觀察 PID 是否變化
?>

PHP 內部長連接實現機制

mysql_pconnect 根據 Apache 進程 ID 生成 Hash Key,在進程級別的 persistent_list 中查找/儲存連線資源。

// 簡化版核心邏輯 (PHP 源碼 ext/mysql/php_mysql.c)
$user = php_get_current_user();  // 取得進程唯一標識
$hashed_details = "MySQL__${user}_";

// 在 persistent_list 中查找
if (zend_hash_find(&EG(persistent_list), $hashed_details, ...) == FAILURE) {
    // 不存在:建立新連線並存入 hash 表
    zend_hash_update(&EG(persistent_list), $hashed_details, ..., $new_le);
} else {
    // 存在:直接復用連線資源
    $mysql = $le->ptr;
}

MySQL 端關鍵參數:wait_timeout vs interactive_timeout

預設值陷阱

兩者預設均為 8 小時 (28800 秒),極易導致連線堆積。

觀察連線狀態

<?php
$conn = mysql_pconnect("localhost", "root", "123456");
echo "MySQL Thread ID: " . mysql_thread_id($conn) . "<br>";
echo "Apache PID: " . getmypid();
?>

對照 MySQL SHOW PROCESSLIST 觀察 Command=Sleep、Time 遞增。

參數調整建議 (my.cnf)

[mysqld]
wait_timeout = 30          # 非互動式連線閒置超時
interactive_timeout = 60   # 互動式連線閒置超時

連線類型判斷

  • 預設 mysql_pconnect → 非互動式 → 受 wait_timeout 控制
  • mysql_pconnect(..., MYSQL_CLIENT_INTERACTIVE) → 互動式 → 受 interactive_timeout 控制

黃金平衡原則

Apache KeepAliveTimeout ≥ MySQL wait_timeout

確保 Apache 釋放連線前,MySQL 已主動清理閒置連線,避免「僵屍連線」佔用 max_connections。

實戰調優清單

層面建議值說明
Apache KeepAliveTimeout15-30 秒視網站流量調整,過長浪費進程槽
MySQL wait_timeout10-30 秒略小於 KeepAliveTimeout
MySQL max_connections500-2000配合伺服器記憶體設定
PHP mysql_pconnect謹慎使用高併發下易爆連線數,建議改用連線池

現代替代方案

  • PDO::ATTR_PERSISTENT:PDO 原生支援
  • 連線池中介軟體:ProxySQL、MaxScale、PgBouncer
  • 應用層連線池:Swoole、Workerman 長驻進程模型
  • 無狀態架構:短連接 + 高效能資料庫 + 連線複用優化

總結

mysql_pconnect 看似美好,實則是「雙邊協作」的脆弱平衡。現代高併發架構建議:放棄長連接,採用短連接 + 連線池中介 + 資料庫參數調優,更穩定可控。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved