天天看點

mysql 連接配接池洩露_一次 Druid 連接配接池洩露引發的血案!

最近某個應用程式老是卡,需要重新開機才能解決問題,導緻被各種投訴,排查問題是 Druid 連接配接池洩露引發的血案。。

異常日志如下:

ERROR - com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 50, maxActive 50, creating 0

at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1512)

at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:1255)

at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:5007)

at com.alibaba.druid.filter.stat.StatFilter.dataSource_getConnection(StatFilter.java:680)

at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:5003)

at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1233)

at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1225)

at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:90)

連接配接池中的連接配接數量已經到達最大值了,到了 60 秒還不能建立連接配接就逾時報錯了。

問題很明顯,肯定是應用程式哪裡用了連接配接但沒有釋放,全局排查代碼又比較艱難,加了三個 Druid 連接配接池配置項,最終定位并解決了問題。

添加以下配置:

這就是連接配接洩露配置項,如果連接配接長時間不歸還,removeAbandoned 打開狀态,超過 removeAbandonedTimeoutMillis 設定的逾時時間,将會強制回收連接配接。

連接配接池初始化時會啟動一個線程,用于檢查并回收連接配接。

參考源碼:

com.alibaba.druid.pool.DruidDataSource#createAndStartDestroyThread

當 logAbandoned 打開狀态時,關閉連接配接同時會記錄當時的堆棧日志,可用于定位到哪些代碼打開了連接配接沒關閉。

abandon connection, owner thread: https-jsse-nio-4443-exec-9, connected at : 1573521883837, open stackTrace

at java.lang.Thread.getStackTrace(Thread.java:1589)

at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:1305)

at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4619)

at com.alibaba.druid.filter.stat.StatFilter.dataSource_getConnection(StatFilter.java:680)

at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4615)

at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1225)

at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1217)

at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:90)

at org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource.getConnection(AbstractRoutingDataSource.java:162)

...

這個配置項雖然可用于排查連接配接池釋放問題,但生産環境小心使用,如果有的業務執行事務的時間比較長,會被誤回收,小心引發另外一個血案。

推薦去我的部落格閱讀更多:

生活很美好,明天見~