問題描述
使用 PDO 時持久連接管理背后的規則/邏輯是什么?
What are the rules/logic behind persistent connection management when using PDO?
網絡服務器
- Windows 7 x64
- 雙核,16GB RAM
- Apache 2.2.17
- PHP 5.3.5
- 通過帶有 IP 地址、端口、服務名稱等的 DSN 字符串連接...
- 沒有用于 DB conn 的 ODBC(現在已經嘗試創建一個 2 小時了,感謝 Oracle!)
數據庫服務器
- Linux 上的 Oracle 10g
- 具有 4GB RAM 的多核
- 專門為我的網絡應用創建的用戶名(是的,它是假的)
- 用戶:網絡用戶
非持久連接
<?php // Open a new connection // Session created in Oracle $dbh = new PDO('DSN', 'webuser', 'password'); // webuser is active in v$session with a SID=1 $dbh = NULL; // webuser removed from v$session // Manually calling $dbh = NULL; will remove the session from v$session // OR // Wait for script EOL so a kill-session command is sent to Oracle? ?>
- 腳本可靠地執行大約需要大約 0.09 秒,框架開銷等...
持久連接
<?php // Open a new connection and make it persistent // Session created in Oracle // Is Apache maintaining some sort of keep-alive with Oracle here? // because I thought php.exe is only alive for the duration of the script $dbh = new PDO('DSN', 'webuser', 'password', array(PDO::ATTR_PERSISTENT => TRUE)); // webuser is active in v$session with a SID=1 $dbh = NULL; // webuser is still active in v$session with a SID=1 $dbh = new PDO('DSN', 'webuser', 'password', array(PDO::ATTR_PERSISTENT => TRUE)); // webuser is still active in v$session with a SID=1 // Manually calling $dbh = NULL; does not kill session // OR // Script EOL does not kill session // ^^ this is good, just as expected ?>
- 腳本在初次訪問時需要約 .12 秒來執行,并帶有框架開銷等......
- 后續執行 take ~.04
我訪問該頁面,
webuser
得到一個SID=1
I visit the page and
webuser
gets aSID=1
我的同事訪問了該頁面,
webuser
獲得了一個額外的SID=2
<- 為訪問此頁面的新計算機沖洗、重復和增加 SIDMy colleague visits the page and
webuser
gets an additionalSID=2
<- rinse, repeat, and increment SID for new computers visiting this page新訪問者不應該重復使用
SID=1
嗎?Shouldn't a new visitor be re-using
SID=1
?歡迎所有答案、建議、替代測試請求、閱讀材料鏈接.
All answers, suggestions, requests for alternate testing, links to reading material are welcomed.
我已經使用 RTFM 一段時間了,而谷歌搜索只產生了微薄的
持久性與非持久性的優勢
博客.I have RTFM'ed for a while and Googling has only produced meager
Advantages of Persistent vs. Non-persistent
blogs.推薦答案
Apaches 的觀點
Apache 有一個父進程.此進程創建子進程來處理傳入 Web 服務器的任何請求.Web 服務器啟動時啟動的初始子進程數量由 apache 配置中的
StartServers
指令配置.這個數字會隨著訪問 Web 服務器的請求數量的增加而增加,直到達到ServerLimit
.Apaches point of view
Apache has one parent process. This process creates child processes that will handle any requests coming to the web server. The initial amount of child processes being started when the web server starts is configured by the
StartServers
directive in the apache configuration. The number goes up as needed with a raising amount of requests hitting the web server untilServerLimit
is reached.如果 PHP(作為 mod_php 運行,作為 CGI 在腳本執行結束時所有資源都被釋放)現在被告知為請求建立與數據庫的持久連接,即使在腳本完成后,該連接也會保持.現在保持的連接是處理請求的 apache 子進程和數據庫服務器之間的連接,并且可以被這個確切的子進程正在處理的任何請求重用.
If PHP (ran as mod_php, as CGI all resources are freed at the end of script execution) is now being told to establish a persistent connection with a database for a request, this connection is hold even after the script finishes. The connection being now hold is a connection between the apache child process which the request was handled by and the database server and can be re-used by any request that is being handled by this exact child process.
如果由于某種原因(不要問我確切的原因),子進程被占用的時間比實際請求的時間長并且另一個請求進來,父 apache 進程將此請求重定向到一個(新)子進程,這可能到目前為止還沒有建立到數據庫的連接.如果在腳本執行期間必須這樣做,它會像您觀察到的那樣引發 SID.現在有兩個連接被apache的兩個不同的子進程持有.
If, for some reason (do not ask me exactly why), the child process is being occupied longer than the actual request and another request comes in, the parent apache process redirects this request to a (new) child process which may has not established a connection to the database up to this time. If it has to during the execution of the script, it raises the SID as you have observed. Now there are two connections be hold by two different child processes of apache.
重要的是要知道,這也會引起很多麻煩.如果在腳本執行過程中出現死循環或中止事務或其他一些甚至不可預測的錯誤,連接將被阻塞且無法重用.也可能發生數據庫的所有可用連接都被使用,但 apache 服務器的另一個子進程試圖訪問數據庫.該進程暫時被阻止,直到數據庫或 apache 釋放連接(超時或自愿終止).此頁面上有關此主題的任何進一步信息:http://www.php.net/manual/en/features.persistent-connections.php
It is important to know, that this can also cause a lot of trouble. If there is an endless loop or an aborted transaction or some other may be even unpredictable error during the script execution, the connection is blocked and can not be re-used. Also it could happen that all of the available connections of the database are used, but there is another child process of the apache server trying to access the database. This process is blocked for the time being until a connection is freed by the database or apache (timeout or voluntarily by termination). Any further information about this topic on this page: http://www.php.net/manual/en/features.persistent-connections.php
我希望我能正確總結我們在評論對話中討論的所有內容,并且沒有忘記任何事情.如果是這樣,請給我一個提示,我會添加它.:)
I hope I got all that we have discussed in our comment conversation summarized correctly and did not forget anything. If so, please, leave me a hint and I will add it. :)
我剛剛讀完了這篇評論.它描述了我在上面總結的過程,并提供了有關如何優化 apache 服務器以更好地與持久連接一起工作的有用信息.不過,它可以在有或沒有 oracle 數據庫后端的情況下使用.你應該看看:http://www.oracle.com/technetwork/articles/coggeshall-persist-084844.html
I just finished reading the article @MonkeyZeus mentioned in this comment. It describes the process I summarized above and provides useful information on how to optimize your apache server to work better together with persistent connections. It can be used with or without oracle database backends, though. You should give a look: http://www.oracle.com/technetwork/articles/coggeshall-persist-084844.html
這篇關于完全理解 PDO ATTR_PERSISTENT的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!
【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!