常見故障之八:JDBC Connection Pools
WebLogic Server中,資料庫連線池是一個經常出問題的地方。下面就總結一下出問題的原因和解決辦法。
1.資料庫連線洩漏
此類問題一般都是由於開發人員沒有正確關閉資料庫連線造成的。比如,使用完Connection後,沒有呼叫Connection.close()方法。
1.1. 診斷方法
在Console中,找到Connection Pools Tab 和Diagnostics,設定以下屬性(不同版本可能略有區別)
Enable Connection Leak Profiling 啟用連線池洩漏的監控。
Enable Connection Profiling 啟用連線池監控。
Inactive Connection Timeout 100 表示100秒後強制回收無效連線。預設0,表示使用完才釋放回連線池。
無需重啟,檢視server的log,查詢“A JDBC pool connection leak was detected”,如果有,看看是哪個類引起的。
下面是一個資料庫連線洩漏的例子:
A JDBC pool connection leak was detected.
A connection leak occurs when a connection obtained from the pool was not closed explicitly by calling close() and then was disposed by the garbage collector and returned to the connection pool.
The following stack trace at create shows where the leaked connection was created.
Stack trace at connection create:
at weblogic.jdbc.wrapper.JTAConnection.init(JTAConnection.java:90)
at weblogic.jdbc.jta.DataSource.getConnection(DataSource.java:468)
at weblogic.jdbc.jta.DataSource.connect(DataSource.java:410)
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:344)
at troubleshooting.servlets.JdbcConnections.service(JdbcConnections.java:97)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:1077)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:465)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:348)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:7047)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3902)
at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2773)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:224)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)
問題解決後,把三個屬性設定回先前的值。
1.2. 解決方法
正確的關閉資料庫連線。具體程式碼如下:
Connection conn = null;
ResultSet rs = null;
preparedStatement pss = null;
try {
conn = dataSource.getConnection(USERID,pASSWORD);
pss = conn.prepareStatement("SELECT SAVESERIALZEDDATA FROM SESSION.pINGSESSION3DATA WHERE SESSIONKEY = ?");
pss.setString(1,sessionKey);
rs = pss.executeQuery();
pss.close();
} catch (Throwable t) {
// 錯誤處理
} finally {
try {
if (conn != null) conn.close();
} catch (Exception e){}
}
2.資料庫連線不夠用
導致資料庫連線不夠用的原因主要有:
(1)某些程式佔用connection時間過長,如果多個使用者同時使用這些程式,則會導致連線不夠用。
(2)執行緒死鎖,無法釋放connection。
2.1. 診斷方法
(1)監控引數:Waiting For Connection High Count
[domain_name]-> Enviroment -> Servers -> [Server] -> Monitoring -> JDBC檢視引數:Waiting For Connection High Count
如果沒有此引數,手工新增進來,該參數列示在沒有可用連線的情況下,應用程式等待連線的最大個數。
調整後的連線池最大值 = 調整前的連線池最大值 + Waiting For Connection High Count。
一般來說,資料庫連線池的大小與最佳併發使用者數相當。
(2)在Server Log中,明確丟擲下列異常:
java.sql.SQLException: Internal error: Cannot obtain XAConnection weblogic.common.resourcepool.ResourceLimitException: No resources currently available in pool BankConnectionPool to allocate to applications, please increase the size of the pool and retry..
at weblogic.jdbc.jta.DataSource.refreshXAConnAndEnlist(DataSource.java:1493)
at weblogic.jdbc.jta.DataSource.getConnection(DataSource.java:455)
at weblogic.jdbc.jta.DataSource.connect(DataSource.java:410)
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:344)
at troubleshooting.servlets.JdbcConnections.service(JdbcConnections.java:80)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:1077)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:465)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:348)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:7047)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3902)
at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2773)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:224)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)
如果此時觀察connection的監控,會發現所有connection 都是Active,而且還有大量請求等待connection。
2.2. 解決方法
(1)提高Maximum Capacity數量,該值一般略大於峰值情況下的資料庫連線數。
Services > JDBC > Connection Pools > BankConnectionPool > Configuration > Connections
(2)重點檢查synchronize程式碼段和涉及資料庫鎖的程式碼。如果有必要,可以檢視thread dump,看看執行緒在忙什麼和等什麼。
3.資料庫連線使用超時
此類問題一般是由於某些資料庫操作時間比較長,超過了Inactive connection timeout的設定。
3.1. 診斷方法
在Server Log中,明確有下列提示,並且在提示後丟擲應用異常:
Forcibly releasing inactive resource "weblogic.jdbc.common.internal.ConnectionEnv@132967d" back into the pool "BankConnectionPool".
這裡無法列出應用異常,因為每個應用都不一樣,不過很有可能會丟擲空指標異常,因為Connection被強制放回池中了,繼續使用一個空物件會丟擲該異常。
3.2. 解決方法
在高階引數中,提高Inactive connection timeout數量。
Services > JDBC > Connection Pools > BankConnectionPool > Configuration > Connections
4.事務超時
此類問題一般是由於某些資料庫操作時間比較長,超過了JTA Timeout Seconds的設定。
4.1. 診斷方法
在Server Log中,明確丟擲異常:
weblogic.transaction.internal.TimedOutException: Transaction timed out after 300 seconds
4.2. 解決方法
提高Services > JTA Configuration > Timeout Seconds數量。
注意,這個引數應該小於Inactive connection timeout的值,因為事務必須在連線超時前完成。
如果想分析究竟是哪些SQL語句導致事務超時,可以開啟日誌AdminServer > Logging > JDBC,選中Enable JDBC Logging,並設定JDBC Log File Name。
參考文獻:
1. http://www.ibm.com/developerworks/cn/websphere/library/bestpractices/closing_and_releasing_jdbc_resources.html
2. http://blog.csdn.net/esky2000/archive/2008/07/22/2689929.aspx
3.
Refer to:http://maping930883.blogspot.hk/2009/03/wls040jdbc-connection.html
1.資料庫連線洩漏
此類問題一般都是由於開發人員沒有正確關閉資料庫連線造成的。比如,使用完Connection後,沒有呼叫Connection.close()方法。
1.1. 診斷方法
在Console中,找到Connection Pools Tab 和Diagnostics,設定以下屬性(不同版本可能略有區別)
Enable Connection Leak Profiling 啟用連線池洩漏的監控。
Enable Connection Profiling 啟用連線池監控。
Inactive Connection Timeout 100 表示100秒後強制回收無效連線。預設0,表示使用完才釋放回連線池。
無需重啟,檢視server的log,查詢“A JDBC pool connection leak was detected”,如果有,看看是哪個類引起的。
下面是一個資料庫連線洩漏的例子:
A JDBC pool connection leak was detected.
A connection leak occurs when a connection obtained from the pool was not closed explicitly by calling close() and then was disposed by the garbage collector and returned to the connection pool.
The following stack trace at create shows where the leaked connection was created.
Stack trace at connection create:
at weblogic.jdbc.wrapper.JTAConnection.init(JTAConnection.java:90)
at weblogic.jdbc.jta.DataSource.getConnection(DataSource.java:468)
at weblogic.jdbc.jta.DataSource.connect(DataSource.java:410)
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:344)
at troubleshooting.servlets.JdbcConnections.service(JdbcConnections.java:97)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:1077)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:465)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:348)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:7047)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3902)
at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2773)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:224)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)
問題解決後,把三個屬性設定回先前的值。
1.2. 解決方法
正確的關閉資料庫連線。具體程式碼如下:
Connection conn = null;
ResultSet rs = null;
preparedStatement pss = null;
try {
conn = dataSource.getConnection(USERID,pASSWORD);
pss = conn.prepareStatement("SELECT SAVESERIALZEDDATA FROM SESSION.pINGSESSION3DATA WHERE SESSIONKEY = ?");
pss.setString(1,sessionKey);
rs = pss.executeQuery();
pss.close();
} catch (Throwable t) {
// 錯誤處理
} finally {
try {
if (conn != null) conn.close();
} catch (Exception e){}
}
2.資料庫連線不夠用
導致資料庫連線不夠用的原因主要有:
(1)某些程式佔用connection時間過長,如果多個使用者同時使用這些程式,則會導致連線不夠用。
(2)執行緒死鎖,無法釋放connection。
2.1. 診斷方法
(1)監控引數:Waiting For Connection High Count
[domain_name]-> Enviroment -> Servers -> [Server] -> Monitoring -> JDBC檢視引數:Waiting For Connection High Count
如果沒有此引數,手工新增進來,該參數列示在沒有可用連線的情況下,應用程式等待連線的最大個數。
調整後的連線池最大值 = 調整前的連線池最大值 + Waiting For Connection High Count。
一般來說,資料庫連線池的大小與最佳併發使用者數相當。
(2)在Server Log中,明確丟擲下列異常:
java.sql.SQLException: Internal error: Cannot obtain XAConnection weblogic.common.resourcepool.ResourceLimitException: No resources currently available in pool BankConnectionPool to allocate to applications, please increase the size of the pool and retry..
at weblogic.jdbc.jta.DataSource.refreshXAConnAndEnlist(DataSource.java:1493)
at weblogic.jdbc.jta.DataSource.getConnection(DataSource.java:455)
at weblogic.jdbc.jta.DataSource.connect(DataSource.java:410)
at weblogic.jdbc.common.internal.RmiDataSource.getConnection(RmiDataSource.java:344)
at troubleshooting.servlets.JdbcConnections.service(JdbcConnections.java:80)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at weblogic.servlet.internal.ServletStubImpl$ServletInvocationAction.run(ServletStubImpl.java:1077)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:465)
at weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:348)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:7047)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:3902)
at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:2773)
at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:224)
at weblogic.kernel.ExecuteThread.run(ExecuteThread.java:183)
如果此時觀察connection的監控,會發現所有connection 都是Active,而且還有大量請求等待connection。
2.2. 解決方法
(1)提高Maximum Capacity數量,該值一般略大於峰值情況下的資料庫連線數。
Services > JDBC > Connection Pools > BankConnectionPool > Configuration > Connections
(2)重點檢查synchronize程式碼段和涉及資料庫鎖的程式碼。如果有必要,可以檢視thread dump,看看執行緒在忙什麼和等什麼。
3.資料庫連線使用超時
此類問題一般是由於某些資料庫操作時間比較長,超過了Inactive connection timeout的設定。
3.1. 診斷方法
在Server Log中,明確有下列提示,並且在提示後丟擲應用異常:
Forcibly releasing inactive resource "weblogic.jdbc.common.internal.ConnectionEnv@132967d" back into the pool "BankConnectionPool".
這裡無法列出應用異常,因為每個應用都不一樣,不過很有可能會丟擲空指標異常,因為Connection被強制放回池中了,繼續使用一個空物件會丟擲該異常。
3.2. 解決方法
在高階引數中,提高Inactive connection timeout數量。
Services > JDBC > Connection Pools > BankConnectionPool > Configuration > Connections
4.事務超時
此類問題一般是由於某些資料庫操作時間比較長,超過了JTA Timeout Seconds的設定。
4.1. 診斷方法
在Server Log中,明確丟擲異常:
weblogic.transaction.internal.TimedOutException: Transaction timed out after 300 seconds
4.2. 解決方法
提高Services > JTA Configuration > Timeout Seconds數量。
注意,這個引數應該小於Inactive connection timeout的值,因為事務必須在連線超時前完成。
如果想分析究竟是哪些SQL語句導致事務超時,可以開啟日誌AdminServer > Logging > JDBC,選中Enable JDBC Logging,並設定JDBC Log File Name。
參考文獻:
1. http://www.ibm.com/developerworks/cn/websphere/library/bestpractices/closing_and_releasing_jdbc_resources.html
2. http://blog.csdn.net/esky2000/archive/2008/07/22/2689929.aspx
3.
Refer to:http://maping930883.blogspot.hk/2009/03/wls040jdbc-connection.html
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26477398/viewspace-1626587/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 0.java開發常見故障Java
- NO.A.0001——zabbix常見故障的處理
- k8s-----常見故障及解析K8S
- org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection 解決辦法SpringFrameworkJDBCOTGExceptionAI
- Oracle RAC常見啟動失敗故障分析Oracle
- oracle資料庫常見故障和解決難度Oracle資料庫
- 普通raid常見故障解和決方案彙總AI
- 伺服器常見故障及解決辦法伺服器
- 經典乾貨:Docker 常見故障排查處理Docker
- 物件池Pools優化物件優化
- Webpack 之常見見招拆招Web
- Java之常見異常 整理集合Java
- 統信UOS系統常見故障及處理方法
- 網路交換機常見故障及解決方法
- 華為雲服務治理 | 微服務常見故障模式微服務模式
- DNS故障的幾種常見原因及解決方法DNS
- 八種常見採購風險,怎麼控制?
- Windows作業系統常見故障問題和解決方案Windows作業系統
- 嵌入式主機板常見故障5問5答
- 串列埠通訊常見的錯誤和故障排除方法串列埠
- rabbitmq 原理、叢集、基本運維操作、常見故障處理MQ運維
- 伺服器故障的常見原因和預防辦法伺服器
- 【故障處理】ORA-28547: connection to server failed, probableServerAI
- TypeScript 之常見型別(上)TypeScript型別
- TypeScript 之常見型別(下)TypeScript型別
- MySQL 之索引常見內容MySql索引
- 面試百問:Redis 常見的故障以及發生場景面試Redis
- 光纖收發器常見故障及對應解決方法
- 八分鐘瞭解快取的常見問題?快取
- 關於Java異常最常見的八大問題Java
- Python新手常見問題八:標準庫模組命名Python
- Java 之 JDBCJavaJDBC
- Java之JDBCJavaJDBC
- NSIS 之 NsDialogs 常見問題解答
- 【伺服器資料恢復】Raid磁碟陣列常見故障解析伺服器資料恢復AI陣列
- 阿特拉斯空壓機馬達常見故障有哪些,該如何維修?
- 三菱PLC常見故障及遠端維護解決方案
- 5種常見的 DNS 故障診斷及問題處理方法DNS
- java.net.ConnectException: Connection refused 異常JavaException