php與mysql的連線

2022-05-17 01:31:59 字數 1948 閱讀 4593

閒來無事研究一下 php 的 mysql 持久連線問題。在 mysql 擴充套件的年代,應該用的是mysql_pconnect,可是那時候我還沒有開始接觸 php, 所以我們直接上 pdo。

首先說一下本次測試用的環境。

738 x 5391468 x 1072

關鍵還要看一下 php 的配置。

738 x 555846 x 636

注意其中的最重要的引數pm.max_children=1, 這決定了只能有乙個 fpm 的 worker 程序來處理所有請求。這樣把問題簡化更容易發現特徵。

我們知道, php 的 fpm 有乙個 master 程序和若干個 worker 程序, 而 worker 程序並不是像最早的 fastcgi 一樣每次處理完乙個請求之後就銷毀, 下次再來請求需要重新啟動。也就是說乙個 worker 程序是可以處理多個請求的。這給「持久連線」提供了理論基礎。 那麼到底它能不能支援持久連線呢?如果支援持久連線, 它的特徵又是什麼呢?下面直接上**。

738 x 5391468 x 1072

反覆執行curl(我給 fpm.org 配置了 hosts), 就可以看到不斷變化的 lastinsertid 了。 但這不是重點, 要看兩個現象。

用 root 賬戶登入 mysql, 執行show processlist;可以看到類似如下的輸出:

738 x 4151920 x 1080

可以看到, 有兩個客戶端和伺服器保持了連線。是誰呢?第乙個是 ubuntu(其實是 debian)維護的 mysql 包自帶的預設管理員使用者, 其實表示的就是當前的這個 mysql cli 連線。另外乙個當然就是剛才呼叫curl通過 php 的 pdo 建立的了。

738 x 5391468 x 1072

現在再來看 general_log,

738 x 4151920 x 1080

可以看到多次請求伺服器端都是同乙個執行緒 id(14). 參考這裡

那麼怎麼驗證它是由當前這個 fpm 的 worker 維持的呢?很簡單, 重啟一下 fpm 再看它有沒有變化就知道了。

sudo systemctl restart php-fpm.service

738 x 1191264 x 204

可以看到乙個新的 worker 已經在工作了。 現在重新訪問剛才的位址

先再去執行一下show processlist;

738 x 4151920 x 1080

可以看到 14 已經不在了。因為維持 14 這個連線的 fpm worker 已經掛了,當然對應的伺服器的執行緒也已經銷毀了。但 15 出現了。那麼這幾次請求用的是不是 15 呢?

當然是。

738 x 4151920 x 1080

所以結論很明顯了,在 fpm 模式下是可以使用 mysql 持久化連線的。

所以理論上也可以實現 mysql 連線池。有時間可以研究一下。想了想是沒有辦法實現連線池的, 因為乙個 worker 只能維持乙個長連線,無法和別的 worker 共享, 只能通過配置pm.max_children來讓 fpm 維持的長連線沒有那麼多不要超過 mysql 的最大連線數.

不過這是乙個危險操作, 因為你也看到了, 我在寫這篇文章的過程中在沒有手動重啟 fpm 程序之前這個長連線是一直保持的,而如果這個 fpm 程序是空閒的, 那麼這個連線就是被浪費的。這有可能導致大量無用的連線占用 mysql 的連線數, 而連線數是有上限的,超過之後就無法再建立新的連線, 導致後續的連線失敗。所以必須設定長連線數的上限, 同時保證 worker 空閒一段時間後退出,(使用pm.max_spare_servers實現)或者再處理若干次請求之後重新啟動(通過pm.max_requests實現), 以保證 mysql 的正常連線數。

mysql與php的連線 PHP 連線mysql

php 連線mysql mysqlhost localhost mysqluser root mysqlpass mysqldata mydata connect mysql connect mysqlhost,mysqluser,mysqlpass or die 錯誤 mysql error my...

php與MySQL的連線

繁寫 echo this is a test echo asdfasdfadsf mysql server name localhost 資料庫伺服器名稱 mysql username root 連線資料庫使用者名稱 mysql password 連線資料庫密碼 mysql database 資料庫...

PHP與Mysql的連線

繁寫 echo this is a test echo asdfasdfadsf mysql server name localhost 資料庫伺服器名稱 mysql username root 連線資料庫使用者名稱 mysql password 連線資料庫密碼 mysql database 資料庫...