關鍵字:ASP.NET, Oracle, 資料庫連接池, 效能瓶頸
摘 要:本文通過筆者所經曆的一個案例,介紹Asp.net串連Oracle因串連池的問題造成的效能瓶頸的現象,以及解決的辦法。
1 問題的發現
2006年下半年,筆者在山東臨淄齊魯石化駐地參與一個項目的開發。公司的另外一個項目《合約管理系統》正處於實施後期階段。該項目採用.Net開發的B/S架構的系統,使用Oracle做後台資料庫。先後兩次發現,當線上使用者較多的時候,用戶端感覺服務系統反應很慢(多數使用者報告在登入介面點擊登入按鈕後,一直處於等待狀態,系統不再反應)。查看伺服器使用方式,CPU和硬碟訪問並不繁忙,記憶體佔用也不是非常大;串連到資料庫沒有發現死結,但是會話非常多,大約在110個左右。開始懷疑是資料庫的進程(Processes)和會話(Sessions)設定的值較低(未安裝時候的預設值,分別為170和150)。但是將這兩個值擴大以後仍舊未解決問題。在第二次發現該問題的時候,我注意到雖然設定值較低,但是當前並未達到這兩個值得上限;同時我也注意到該系統串連資料庫的會話正好是100個,由此我聯想到資料庫連接池。
2 相關資料
查閱過vs.net 2003的協助之後,在
ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.2052/cpguide/html/cpconconnectionpoolingforsqlservernetdataprovider.htm,基本內容如下:
使用連接字串關鍵字控制串連池
SqlConnection 對象的 ConnectionString 屬性支援連接字串鍵/值對,這些鍵/值對可用於調整串連池邏輯的行為。
下表描述了可用於調整串連池行為的 ConnectionString 值。
名稱 |
預設值 |
說明 |
Connection Lifetime |
0 |
當串連返回到池中時,將對它的建立時間和目前時間進行比較,如果時間間隔超過由 Connection Lifetime 指定的值(以秒為單位),則會毀壞該串連。在聚集配置中可以使用它來強制在運行伺服器和剛聯機的伺服器之間達到Server Load Balancer。 如果值為零 (0),則將使池串連具有最大的逾時期限。 |
Connection Reset |
'true' |
確定在從池中移除資料庫連接時是否將其重設。對於 Microsoft SQL Server 版本 7.0,如果設定為 false,將避免在擷取串連時經曆一個額外的往返過程,但必須注意的是串連狀態(如資料庫上下文)不會被重設。 |
Enlist |
'true' |
當為 true 時,如果存在事務上下文,池管理程式將自動在建立線程的當前事務上下文中登記串連。 |
Max Pool Size |
100 |
池中允許的最大串連數。 |
Min Pool Size |
0 |
池中維護的最小串連數。 |
Pooling |
'true' |
當為 true 時,將從相應的池中取出串連,或者在必要時建立串連並將其添加到相應的池中。 |
由此可見,ASP.NET串連資料庫,資料庫連接池預設是開啟的,並且池中允許的最大串連數預設為100。由此基本可以確定,訪問系統收到的阻礙時由於串連池已滿造成的。
該頁面中提到,如果串連池中的串連全部佔用,系統會在串連池之外開啟新的串連。這個說法有疑問,該問題在後面的會體積。
3 問題的確認
為了驗證ASP.NET串連Oracle資料庫時,串連池中的串連達到最大數,新的串連就需要等待串連池中的串連釋放資源,我編寫了一個測試頁面,在頁面裝載的時候,首先開啟10個串連,然後等待20秒鐘後再關閉這些串連。隨後使用測試機開啟兩個測試線程訪問該測試頁面,然後在瀏覽器中開啟於這個測試頁面使用相同串連字串的另外一個頁面,發現後者的確需要等待測試線程訪問的頁面處理完畢之後才可以串連到資料庫。
4 問題的解決
找到問題的癥結所在,我們系統的串連資料庫的字串,增加了Max Pool Size項,根據需要將其設定為200。同時修改了Oracle伺服器的的會話(Sessions)和進程(Progresses)的值以滿足串連會話的需要。
5 疑問
如前所述,資料中提及,如果串連池的串連全部佔用,會建立新的串連。但是在採用預設串連池大小和設定為20個最大串連數的時候,串連池的所有串連全部佔用,新的串連請求並沒有開啟新的串連會話,而是等待串連池中的串連釋放。
但是串連池最大串連數設定為200個的時候,該系統的串連曾經一度超過200個上限,達210多個。由此可以判斷超出的串連請求在串連池之外建立了新的串連會話,符合了資料中的論述。對此疑問,煩請知情者闡述一下自己的觀點。
6 補充
在串連字串修改之後,原有的串連池會重新構建,這一特性是否可以在何種情況下應用?
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1358594