串連池與不穩定網路

來源:互聯網
上載者:User

        串連池技術,大大的提升了應用程式的效能,但是如果不瞭解串連池的使用情境和原理,就茫然使用串連池,.net預設使用串連池,大多數人會選擇使用串連池的預設設定,這樣帶來的後果往往也是慘痛的,也許你將花費更大的代價去尋找因為串連池的不當使用而帶來的未知問題。

         在一個項目中,因為串連池的不當使用而帶來了一個慘痛的教訓。一般我們的應用程式如果部署在一個較為穩定的網路環境中,預設使用串連池可能不會有什麼問題,如果一旦部署到一個不穩定的網路環境,你就必須得絞盡腦汁去面對那些應用不穩定代帶來的折磨。

        首先,大概說一下串連池的原理

       

        資料庫連接池允許應用程式重用已存在於池中的資料庫連接,以避免反覆的建立新的資料庫連接。這種技術能有效提高應用程式的伸縮性,因為有限的資料庫連接能夠給大量的客戶提供服務。這種技術同時也提高的系統效能,避免了大量建立新串連的開銷。

  開發一個具有伸縮性的、高效能應用程式應該最大限度的減少建立串連所花費的時間,保持資料庫連接最大限度的有效,以存取資料。當一個資料庫連接關閉時,它只是由串連池收回以待重用,並未真正釋放。但是,如果串連池被釋放,資料庫連接將會被釋放掉。

  開發人員應當注意不要依賴記憶體回收機制去釋放資料庫連接,因為當參數超出範圍時,資料庫連接並沒有得必要的關閉,這種資料庫資源泄漏將導致建立新串連時拋出串連錯誤。

  建立資料庫連接池

  當開啟一個資料庫連接時,一個資料庫連接池也就建立了。資料庫連接池的建立與資料庫連接字串精確的相關(包括空格、大小寫)。所有的串連池是根據連接字串來區分的。在建立一個新的資料庫連接時,如果連接字串不完全相同,將建立不同的串連池。

  一旦資料庫連接池被建立,它將一直存在直到該進程結束。維護一個非使用中的串連池幾乎不需要什麼系統開銷。

  串連池中的資料庫連接
  
  串連池根據唯一的連接字串被建立。在串連池被建立的同時,串連池將建立最小的資料庫連接,當串連不夠用時,串連池將逐個添加資料庫連接直到達到最大串連數,此後的串連請求將被加入請求隊列裡。當調用資料庫連接對象的Close方法或Dispose方法時,資料庫連接將被資料庫連接池回收。

  當資料庫連接使用完成後,要調用Close方法或Dispose方法將它返回串連池。沒有顯式釋放的資料庫連接可能會沒有返回串連池。

      應用程式在建立串連時,如果啟用串連池,會在串連池維護一個邏輯串連和一個物理串連。

      在不穩定網路環境中,如防火牆,網閘(內外網部署應用)物理隔離,在級聯交換器出現在網路阻塞的情況下出現網路瞬斷的機率較大

       內外網系統互動,出現網路瞬斷時,再建立網路串連就很容易出現ora-03113 通訊通道的檔案結束或ora-03114無法串連到oracle,這兩個錯誤在網上的解釋大部分都是因為網路導致。那麼針對這兩種錯誤,如果沒有必要使用串連池就設定連接字串Pooling=false,因為在使用串連池時,一旦出現網路瞬斷,串連池裡的串連物理串連已經中斷,但邏輯串連依然存在,當下次有新的請求時,串連池就很有可能將死串連分配出去,就會出現上面的錯誤。如果出現ora-03114隻能重新串連。
       

        以下之前解決這個問題時的步驟,之前寫的一個總結,但是最終依然沒有根治,最終不使用串連池不再出現錯誤,

      簡訊中心服務開發完成後,在測試經常發現一個oracle錯誤:ORA-03113,而且只要一發生這個錯誤,簡訊服務就不能正常提供服務。發生的這個錯誤還是很有規律的,就是在業務繁忙時是不會發生這個錯誤的,只有在服務長時間空閑時才發生(一般是超過5分鐘沒有操作的情況下)。開始以為是oracle會自動切斷不活動的串連,但是查看oracle的session日誌後,發現oracle並沒有主動切斷資料庫連接,而且這個資料庫連接是“莫名其妙”的斷開的,也即不是用戶端斷開的(由於程式中使用了資料庫連接池,串連池會每隔一定時間將不活動的串連關閉)。然後為了查看到底是什麼問題,我們就在資料庫端和用戶端同時監視串連的情況(在資料庫端監視資料庫連接,在用戶端監視TCP串連數,oracle使用的1521連接埠通訊)。這時候發現了一個有趣的問題:就是當出現ORA-03113錯誤時,資料庫端的session顯示的串連很好,但是在用戶端就會發現大量的僵死的TCP串連(串連未完全關閉,狀態顯示是CLOSING)。這時我們就猜測可能是中間的網路環境導致TCP串連非正常關閉。諮詢了“網管”後,得知應用伺服器和資料庫伺服器之間要通過網閘,但是網管說網閘不會切斷串連的。經過查詢資料後(請看這一篇文章:http://www.laoxiong.net/oracle_and_firewall.html),發現我們的情況和文章上的很相似,我們就懷疑網關有TCP串連拆除功能(這個需要在落實下,摸清網閘的功能和網閘到底能對網路產生多大的影響)。經過一番測試後,最中定位到網閘應該有定時拆除TCP串連的功能(因為如果業務比較頻繁的話,資料庫連接是暢通的,只要在業務閒置情況下才會出現這個問題)。

問題解決思路:

第一步:我們打算先從串連池配置開始,這些僵死串連對串連池最大的影響就是使串連池認為這些串連還是暢通的,當程式開啟一個串連時,串連池就會返回一個僵死串連,這時候在僵死串連上操作就會發生ORA-03113錯誤。我們的思路就是將串連池關閉串連的時間縮短。盡量市空閑串連在僵死前將其關閉然後重建立立串連(注意:這樣會使串連池效能有所下降)。但是經測試,這個方法的效果並不是很好,因為串連僵死的時間並不固定,所以無法設定一個合適的時間讓串連池關閉串連。

第二部:使用oracle DCD功能,也就是設定sqlnet.ora的sqlnet.expire_time參數,讓oracle定期發送心跳包使串連保活,但是這個方法還是有一個問題的,就是應用的心跳包會逾時(TCP的keepalive屬性導致)。所以為了使oracle和用戶端儘早發現串連斷開,需要設定TCP的keepalive參數(Windows需要設定註冊表,LINUX需要設定相應的設定檔),這樣可以解決短串連問題(這裡的短串連指程式使用的短串連,也就是在需要使用資料庫時才申請串連,快速完成事務,然後關閉串連,由於使用了串連池,所以串連並沒有關閉,只是歸還到串連池而已)。

第三部:短串連問題解決了,但是長串連還是照樣會出現ORA-03113錯誤(使用長串連的是oracle AQ輪詢線程,該線程會不停對AQ隊列進行一次出隊操作,逾時時間是5m,以此來從隊列裡獲得簡訊資料)。經實驗檢測是因為在等待的這段時間內,資料庫連接斷開所導致。所以我們就將出隊操作的時間縮短到1m,這樣就是該串連一直有活動,這樣就使ora-03113的錯誤發生機率降到了最低。

最終的解決方案:

1.       使用oracle 的DCD國內(設定sqlnet.expire_time參數),設定作業系統的keepalive參數。

2.       針對短串連和長串連分別採用不同的資料庫連接池策略,短串連使用資料庫連接池,並設定串連保活時間,這樣可以是串連池儘可能早的發現僵死串連。對於常串連,則不使用資料庫連接池,一旦發生ORA-03113錯誤,說明此串連已經失效,這時就關閉此串連,並申請新的串連。

3.       縮短oracle AQ的出隊等待時間,這樣可以是串連經常有操作。但是這樣又出現了第二個問題ORA-25228錯誤(隊列出隊逾時)。隨意最後隊列的異常處理為:ORA-03113 關閉串連,重新申請串連,ORA-25228 不進行任何操作,直接進行下一次的出隊操作。

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.