別讓防火墻阻塞了數據庫連接
在我進(jìn)行的技術(shù)支持的項目中,有不少情況下,防火墻的設置會(huì )給J2EE應用帶來(lái)一些麻煩。你遇上過(guò)嗎?

通常的Web應用都是無(wú)狀態(tài)的連接,一般來(lái)說(shuō)對于防火墻是非常友好的。但是,大多數JavaEE應用服務(wù)器都有連接池的概念。為了提高性能,應用服務(wù)器會(huì )預先打開(kāi)并保持一些和后臺數據庫服務(wù)器、LDAP服務(wù)器或其他服務(wù)器的連接。這些連接通常會(huì )將TCP的連接永久保持,除非發(fā)生了意外的情況。
我有幾個(gè)項目發(fā)生的問(wèn)題都是應用服務(wù)器和數據庫之間由于安全級別的問(wèn)題,設有不同的防火墻。在系統運行的時(shí)候,偶爾會(huì )發(fā)生數據庫連接無(wú)法獲得的錯誤(在系統很閑的時(shí)候)??蛻?hù)懷疑應用服務(wù)器的不穩定性。
通過(guò)各種工具的分析(snoop),發(fā)現當應用服務(wù)器的數據庫連接出現問(wèn)題的時(shí)候,數據庫這端沒(méi)有任何問(wèn)題,所有的Session連接都在,但是從應用服務(wù)器發(fā)過(guò)來(lái)的TCP請求沒(méi)有到達數據庫服務(wù)器。是中間的防火墻阻斷了數據庫的連接。在一個(gè)空閑的TCP連接上,可以很長(cháng)時(shí)間沒(méi)有任何的數據流,許多TCP/IP的初學(xué)者都對此感到驚奇。因此當數據庫連接長(cháng)時(shí)間不用(這種情況很常見(jiàn),例如連接池中有10個(gè)連接,由于負載很小,一直只用到前幾個(gè))。一般來(lái)說(shuō),防火墻軟件都會(huì )定時(shí)檢查空閑的連接,并將它們阻斷,來(lái)保證一些異常的中斷連接被清除。
這樣,我們對數據庫連接問(wèn)題的原因找到了,由于空閑的數據庫連接長(cháng)時(shí)間不用被防火墻給阻斷是主要的原因。被阻斷了的數據庫連接在使用的時(shí)候不會(huì )自動(dòng)重新連接嗎?大多數應用服務(wù)器所使用的專(zhuān)業(yè)的數據庫連接池都會(huì )有自動(dòng)重新連接來(lái)解決這個(gè)問(wèn)題。也有一些客戶(hù)使用自己的連接池,或者一些簡(jiǎn)單的開(kāi)源的方案,沒(méi)有自動(dòng)重聯(lián)的功能,導致應用不可用。
就算有的連接池能夠自動(dòng)重連中斷的連接,也不會(huì )時(shí)時(shí)刻刻都去檢查這些在連接池中的連接是否被可用。因為這種檢查非常消耗時(shí)間,還會(huì )影響應用,因此會(huì )每隔幾分鐘檢查一次。在間隔時(shí)間內發(fā)生的連接中斷仍然會(huì )引起系統的錯誤。
另外的解決方案就是從數據庫服務(wù)器端進(jìn)行配置,保證連接的暢通。例如在Oracle中可以設置SQLNET.EXPIRE_TIME小于防火墻的中斷時(shí)間,就能夠是Oracle的數據庫連接在沒(méi)有數據交換的情況下,由服務(wù)器端自動(dòng)發(fā)出探測的數據報,使得防火墻不再認為數據庫連接是空閑的連接。
聯(lián)系客服