深入理解phpredis的pconnect方法

2021-07-24 12:34:24 字數 3688 閱讀 5456

pconnect(), phpredis中用於client連線server的api。

close or

endof request until

the php process ends.

這是api說明中的一句原文

那麼問題來了:

php process ends是指一次php執行完結,還是fpm的終結?如果是後者,那意味著即使一次php執行完畢,redis連線也不會被釋放,下一次執行時redis連線會被重用。

the connection will not be closed on close是說如果使用了pconnect, 即使在**中顯示的呼叫close(), 也不會關閉連線?

帶著這兩個問題,我們做下實驗,深入看一下pconnect究竟做了些什麼。

環境:

nginx + fpm

php5.3

我們將fpm配置為:

pm.max_children = 1

pm.start_servers = 1

pm.max_spare_servers = 1

這樣,我們的頁面請求會由乙個確定的fpm程序執行,方便strace跟蹤。

對應頁面請求的php**:

$ip

="10.136.30.144";

$port

=7777;

$redis

=new redis();

$redis

->pconnect($ip, $port, 1);

$key

="test";

$value

="this is test";

$redis

->

set($key, $value);$d=

$redis

->get($key);

var_dump($d);

**的功能很簡單,連線redis,先設定乙個值,再取出。

思路:

使用strace觀察fpm的系統呼叫,如果連線的生命週期是一次php執行,那麼每次頁面呼叫,都會有connect系統呼叫,用以連線redis;如果連線的生命週期是fpm的終結,那麼只有第一次頁面呼叫會有connect系統呼叫 ,之後由於連線被重用,無需connect,直接發命令請求即可。

啟動乙個新的fpm(程序號28082)。

執行:

strace -p

28082

-s1024

-o redis_1

記錄一次頁面請求的系統呼叫。如下圖所示:

可以看到程序先建立了socket連線(檔案描述符為9)。然後給reids發一系列命令,最終取到「this is test」的結果串。且沒有關閉連線相關的redis命令或系統呼叫。

頁面請求結束後,我們執行:

可以看到,fpm程序仍然保有乙個到10.136.30.144的reids連線,其檔案描述符為9(這與strace的結果一致)。

執行:

strace -p

28082

-s1024

-o redis_2

記錄第二次頁面請求的系統呼叫,得到下面結果。

與第一次請求的區別是:省去了建立連線的過程,直接傳送reids命令,得到結果!

再使用lsof -n -p 28082檢視fpm開啟的檔案描述符,結果與上檔案相同。

說明,連線的確是被重用的,沒有新建。

執行第6次頁面請求(因為我們在準備工作中的配置,此時fpm已經是乙個新的程序了),用lsof檢視程序開啟的檔案描述符。

我們發現,雖然仍然有描述符為9的reids連線,但兩個tcp連線的臨時埠不同了,也就是連線改變了!

至此,我們得出問題1的結論:

當使用pconnect時,連線會被重用,連線的生命週期是fpm程序的生命週期,而非一次php的執行。。

為了對比,我們先看一下,使用connect連線redis,並呼叫redis->close()的系統呼叫。(將上述**中的pconnect改為connect, 同時在最後加入redis->close()

我們看到,除了建立連線外,在程式結尾,還向reids傳送了quit命令,並關閉了連線的檔案描述符。

接下來,我們看在使用pconnect後,redis->close()有何表現

**調整為:

$ip

="10.136.30.144";

$port

=7777;

$redis

=new redis();

$redis

->pconnect($ip, $port, 1);

$key

="test";

$value

="this is test";

$redis

->

set($key, $value);$d=

$redis

->get($key);

var_dump($d);

$redis

->close();

try

catch (exception $e)

我們直接看第2次執行頁面請求的系統呼叫

並沒有建立連線,同樣是直接傳送命令得到結果。說明連線被重用。同時,沒有向reids server傳送quit命令,也無關閉連線的系統呼叫。

但注意,頁面請求的返回結果:

至此,我們得出問題2的結論:

如果**中使用pconnect, close的作用僅是使當前php不能再進行redis請求,但無法真正關閉redis長連線,連線在後續請求中仍然會被重用,直至fpm程序生命週期結束。

當使用pconnect時,連線會被重用,連線的生命週期是fpm程序的生命週期,而非一次php的執行。如果**中使用pconnect, close的作用僅是使當前php不能再進行redis請求,但無法真正關閉redis長連線,連線在後續請求中仍然會被重用,直至fpm程序生命週期結束。

深入理解C語言 深入理解指標

關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...

mysql 索引深入理解 深入理解MySql的索引

為什麼索引能提高查詢速度 先從 mysql的基本儲存結構說起 mysql的基本儲存結構是頁 記錄都存在頁裡邊 各個資料頁可以組成乙個雙向鍊錶每個資料頁中的記錄又可以組成乙個單向鍊錶 每個資料頁都會為儲存在它裡邊兒的記錄生成乙個頁目錄,在通過主鍵查詢某條記錄的時候可以在頁目錄中使用二分法快速定位到對應...

深入理解C語言 深入理解指標

關於指標,其是c語言的重點,c語言學的好壞,其實就是指標學的好壞。其實指標並不複雜,學習指標,要正確的理解指標。指標也是一種變數,占有記憶體空間,用來儲存記憶體位址 指標就是告訴編譯器,開闢4個位元組的儲存空間 32位系統 無論是幾級指標都是一樣的 p操作記憶體 在指標宣告時,號表示所宣告的變數為指...