問題
Cannot get a connection, pool error Timeout waiting for idle object
原因
db.properties中配置的maxWait為連接池獲取mysql連接最大等待時間,超過了這個時間仍然沒獲取到就會報這個錯。
深入分析一下為啥會獲取不到Mysql連接,手動用來瀏覽器請求發送,發現當連接達到MaxActive時會獲取不到,而剩下的50個都在Sleep狀態,原來是用完后沒有回收導致的。
原因1
應用程序沒有很好的關閉使用后的連接
方案1:
請檢查自己的應用程序是否正確關閉了數據庫連接,注意一定要放到finally中關閉。(不推薦,讓數據庫連接池去管理連接)
方案2:
如果確實無法排查出具體哪些代碼沒有關閉數據庫連接,可以通過配置參數完成自動回收,並記錄回收日志,以便於定位問題代碼;tomcat中連接池的配置自動回收參數為:removeAbandoned、 removeAbandonedTimeout、logAbandoned三個。(推薦)
#驗證使用的SQL語句 validationQuery SELECT 1 #池中的連接空閑30分鍾后被回收 minEvictableIdleTimeMillis 18000 #每30秒運行一次空閑連接回收器 timeBetweenEvictionRunsMillis 10000 #借出連接時不要測試,否則很影響性能 testOnBorrow false testWhileIdle true #程序中的連接不使用后是否被連接池回收 #DBCP 2.0.1 (該版本要使用removeAbandonedOnMaintenance和removeAbandonedOnBorrow) #removeAbandoned=true removeAbandonedOnMaintenance=true removeAbandonedOnBorrow=true #數據庫連接過多長時間不用將被視為被遺棄而收回連接池中(單位秒)。(為配合測試程序才配置為30秒)
removeAbandonedTimeout=30
mysql等待時間要設為8小時,連接全部交給連接池管理。
DBCP官網:https://commons.apache.org/proper/commons-dbcp/configuration.html
原因2
應用壓力過大,確實無法獲取空閑連接
方案1:
這種情況可以調整maxActive、maxIdle、maxWait等連接池的容量和超時限制等參數以獲取更大的連接池容量和等待時間。