2012-12-05 19 views
1

PHP具有的衆所周知的功能或一些持久的版本,如mysql_pconnect(不建議使用)pfsockopen持續功能如何工作?

從我讀過,我的理解是這樣的功能緩存第一次調用產生,需要時可重用的資源。

  • 但是,例如與pfsockopen套接字時發生了什麼事,當它是 緩存?
  • 它仍然打開並連接?
  • 如果是這樣, 「睡眠」時間期間收到的潛在數據會發生什麼情況?
  • 這種緩存連接的TTL是什麼?

長話短說,所有的「p」功能如何在後臺真正起作用?關於這一切的官方文檔接近於零

回答

1

有問題的資源沒有被真正緩存,而不是真正意義上的緩存。這些連接一直保持打開狀態,直到腳本終止或直到您調用將其關閉的適當函數(因此,如果您想使用持久連接,請不要撥打例如mysql_close())。

現在,真正的問題是 - 「直到腳本終止」是什麼意思。根據當前使用的PHP SAPI,這可能有所不同,也可能不可能,但讓我們以Apache支持HTTP/1.1 + mod_php爲例 - 它是最流行和最容易解釋的...

HTTP /1.1是必需的,因爲它具有Keep-Alive - 對於無狀態協議來說很奇怪。當你訪問一個頁面時,Apache在一個線程或一個新的系統進程下運行你的PHP腳本。 這裏就是catch - 你的腳本確實執行完整,但是Apache不會終止有問題的線程或進程,從而使它可以保持持續打開的資源。到底是怎麼做的我不確定我可以解釋,但Keep-Alive會將您的下一個HTTP請求附加到相同的線程或進程ID,從而可以重用該資源。 第二部分更多的是基本的完整性檢查 - 如果您使用的是相同的「選項」和/或您用來創建它的憑證,則只能附加到持續連接。因此,如果您撥打mysql_connect()使用不同的用戶名 - 它將創建一個新的連接並且不會重複使用舊的連接(它的簽名不匹配)。但是,假定這個腳本被重新執行,這在大多數情況下只是一個「熱門」。

我希望這對你有意義,爲了充分理解它的工作原理,我花了幾個小時的試驗。您可以在php.net上閱讀更多關於它的文章 - 該文章被命名爲「持久數據庫連接」,但這僅僅是因爲最初的持久連接僅適用於數據庫 - 所描述的行爲對於所有其他等同物都適用。

編輯:

忘記回答您更多具體的問題:

  • 但爲例與pfsockopen發生什麼事到插座時,它的緩存?

    什麼也沒有 - 只是保持活着,如上面已經解釋過的。

  • 它仍然打開並連接?

  • 如果是這樣,什麼發生在「睡眠」時間收到了潛在的數據?

    它等着你讀它。

  • 這種緩存連接的TTL是什麼?

    特別是我無法回答 - 它可能取決於您傳遞給p *函數的選項,您的php.ini設置和/或您連接的內容。它也可能是一個硬編碼的值,對所有這些都是不同的。

+0

這是一個很好的回答謝謝! – grunk

1

當一個請求被提供時,有幾個關閉機制的「層」會做一些垃圾收集。如果你使用的SAPI在每次請求後都沒有拋出所有的東西(例如fcgi或apache處理程序),那麼一些數據結構會在請求之間「生存」。其中之一是一個名爲「EG(persistent_list)」的散列表,將其視爲一個php數組$ EG_presistent_list,它不會在請求之間移除。
現在,當你的腳本調用pfosckopen($主機,$端口,...)的實施確實(或多或少 - 遺憾的過於簡單化)以下

$persistentKey = "pfsockopen__$host:$port"; 
$stream= $EG_persistent_list[$persistentKey]; 
if ($stream) { 
    // this one looks up which module creates such a stream 
    // and "asks" it to check whether this stream may still be working 
    if (!CHECK_LIVENESS($stream)) { 
     $stream = null; 
    } 
} 

if (!$stream) { 
    $stream = createANewOne(...); 
    $EG_persistent_list[$persistentKey] = $stream; 
} 
return $stream; 

(在mysql_pconnect()實現的作用有點有點不同 - 但只有一點點;它仍然查找像$ EG_persistent_list [「mysql_ $ host_ $ port ...」]的條目,如果它不存在,則在那裏放置一個新條目。

Inbetween請求中沒有任何事發生在套接字上,它或多或少就好像您的腳本執行了sleep($n)。如果在下次返回緩存資源時查找資源,則流的處理程序實現會說「它可能還可以」。

看到:在http://svn.php.net/viewvc/php/php-src/trunk/ext/standard/fsock.c?revision=321634&view=markup

  • _php_stream_xport_create(...)