標籤:web 文檔 row 單例模式 ... 兩種 and tin 持久
指令碼代碼:
<?phptry { $dbh = new PDO(‘mysql:host=localhost;dbname=test‘, ‘root‘, ‘root‘);} catch (PDOException $e) { exit(‘串連資料庫失敗1‘);} finally { echo "串連成功1\n";}try { $conn = new PDO(‘mysql:host=localhost;dbname=test‘, ‘root‘, ‘root‘);} catch (PDOException $e) { exit(‘串連資料庫失敗2‘);} finally { echo "串連成功2\n";}try { $pdo = new PDO(‘mysql:host=localhost;dbname=test‘, ‘root‘, ‘root‘);} catch (PDOException $e) { exit(‘串連資料庫失敗3‘);} finally { echo "串連成功3\n";}echo "保持串連中...\n";sleep(10);echo "執行結束\n";
CLI執行:
[email protected]:/home/www/wenda/webroot# php index.php串連成功1串連成功2串連成功3保持串連中...執行結束
在指令碼sleep過程中,查看mysql的串連資訊:
mysql> show processlist;+----+------+-----------+------+---------+------+----------+------------------+| Id | User | Host | db | Command | Time | State | Info |+----+------+-----------+------+---------+------+----------+------------------+| 3 | root | localhost | NULL | Query | 0 | starting | show processlist || 24 | root | localhost | test | Sleep | 6 | | NULL || 25 | root | localhost | test | Sleep | 6 | | NULL || 26 | root | localhost | test | Sleep | 6 | | NULL |+----+------+-----------+------+---------+------+----------+------------------+4 rows in set (0.00 sec)
可以看到一個指令碼的執行產生了三個資料庫連接,但是如果將後面的執行個體化的pdo執行個體賦值給之前執行個體化的pdo執行個體,則新的串連會替換掉前一個串連,而不會產生新的串連。所以我們在編程過程中,應該避免多次執行個體化pdo,而產生不必要的資料庫效能消耗。
解決方案:
1. 封裝一個單例模式的類,該類執行個體化的過程就是建立pdo串連的過程。我們要建立資料庫連接時,不是手動執行個體化pdo,而是去擷取這個類的執行個體。
2. 執行個體化pdo類時,設定 持久串連 參數:
<?php$dbh = new PDO(‘mysql:host=localhost;dbname=test‘, $user, $pass, array( PDO::ATTR_PERSISTENT => true));?>
官方文檔的引用:
很多 web 應用程式通過使用到資料庫服務的持久串連獲得好處。
持久串連在指令碼結束後不會被關閉,且被緩衝,當另一個使用相同憑證的指令碼串連請求時被重用。持久串連緩衝可以避免每次指令碼需要與資料庫回話時建立一個新串連的開銷,從而讓 web 應用程式更快。
- 官方所說的
指令碼結束,在fpm模式下就是指一次用戶端請求的結束。另一個使用相同憑證的指令碼也就可以對應成另一個使用相同資料庫連接憑證的用戶端請求。首先我們要知道,這兩次用戶端的請求是根據fpm-workers的空閑情況,被分配給某個worker去執行的,所以兩次請求被分配到同一個worker的可能性很低。接著,我們闡明下面的情景。 2. 開啟持久串連之後,資料庫連接是被緩衝於fpm進程之中的。如果某個fpm-worker進程中已經緩衝了持久串連,此時可能出現如下兩種情況:
- 當指令碼中再次執行帶 ATTR_PERSISTENT 參數的pdo串連時,會複用之前的串連,而不會產生新的串連。
- 當指令碼中再次執行不帶 ATTR_PERSISTENT 參數的pdo串連時,還會再次產生一個新的資料庫連接。
一個php指令碼執行中執行個體多次PDO,會建立多次資料庫連接。