阿里Druid數(shù)據(jù)連接池引發(fā)的線上異常解決
前言
事件起因:項目使用了activiti工作流,系統(tǒng)是由老的spring mvc項目改造成的spring boot項目,數(shù)據(jù)庫鏈接池從dbcp切換到druid,新系統(tǒng)上線后,同事多次系統(tǒng)隔一段時間后數(shù)據(jù)查詢就很慢,基本出不來。
由此開始了線上bug排查之路。這個問題從一開始就模糊定位到數(shù)據(jù)庫層面的問題,因為只有和數(shù)據(jù)相關(guān)的操作會很慢,其他服務不受影響,并且在中午休息時沒有問題,在下午剛上班后不就出現(xiàn)。
過程一:定位工作流
首先第一反應是看日志:日志一切正常,并沒有任何異常信息拋出,然后將日志級別調(diào)整到debug,發(fā)現(xiàn)了一些問題,中午休息時,用戶沒有操作的情況下,日志一直在輸出jpa的連接信息,最后定位是工作流的異步執(zhí)行器在輪詢,因為在spring boot環(huán)境下spring.activiti.async-executor-activate=true默認是true的,如果不需要使用可以設置為false,改完后情況依舊
過程二:定位JPA的OpenEntityManagerInViewInterceptor
使用OpenEntityManagerInViewInterceptor后服務端在接收到一個請求的時候開啟EntityManager,在請求結(jié)束的時候才去關(guān)閉這個EntityManager,所以在用戶數(shù)多,并發(fā)高,操作耗時的情況下會造成數(shù)據(jù)連接不夠用的情況,而我們的業(yè)務有這個特征。
在spring boot環(huán)境中,OpenEntityManagerInViewInterceptor默認是開啟的,然而我們使用spring.jpa.open-in-view=false關(guān)閉后,問題依舊,不過比之前的間隔時間久一點了
過程三:定位Druid,真正的罪魁禍首
使用top定位到程序pid,然后使用jstack -l 2591 >>dump.out 拿到當前堆??煺蘸蟀l(fā)現(xiàn)如下
"http-nio-8080-exec-54" daemon prio=10 tid=0x0000000000e61000 nid=0xcc9 waiting on condition [0x00007f4a753d4000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000007a143f230> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043) at com.alibaba.druid.pool.DruidDataSource.takeLast(DruidDataSource.java:1732) at com.alibaba.druid.pool.DruidDataSource.getConnectionInternal(DruidDataSource.java:1330) at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:1198) at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4619)
所有的請求都被druid的獲取連接操作阻塞了,最后看源碼如下
因為數(shù)據(jù)鏈接沒有釋放,連接池中無可用連接,導致請求被阻塞了
到這里基本上就是真相了,最后換成spring boot自帶的連接池tomcat jdbc后一切正常
后記:
定位到問題后,發(fā)現(xiàn)網(wǎng)上很多人遇到了連接泄露的情況,可見druid的官方issue,如https://github.com/alibaba/druid/issues/1160
不過druid也提供了相應的方案,如下
雖然官方說可能是應用自己導致連接未被釋放導致連接泄露,但是為什么切換別家的連接池后就毛事都沒有呢,元芳,你怎么看呢?
以上就是阿里Druid數(shù)據(jù)連接池引發(fā)的線上異常解決的詳細內(nèi)容,更多關(guān)于Druid數(shù)據(jù)連接池線上異常的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
springcloud干貨之服務注冊與發(fā)現(xiàn)(Eureka)
這篇文章主要介紹了springcloud干貨之服務注冊與發(fā)現(xiàn)(Eureka) ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01Spring Boot 捕捉全局異常 統(tǒng)一返回值的問題
這篇文章主要介紹了Spring Boot 捕捉全局異常 統(tǒng)一返回值,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-06-06詳解Spring-bean的循環(huán)依賴以及解決方式
這篇文章主要介紹了詳解Spring-bean的循環(huán)依賴以及解決方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-09-09在攔截器中讀取request參數(shù),解決在controller中無法二次讀取的問題
這篇文章主要介紹了在攔截器中讀取request參數(shù),解決在controller中無法二次讀取的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10Java編程實現(xiàn)基于用戶的協(xié)同過濾推薦算法代碼示例
這篇文章主要介紹了Java編程實現(xiàn)基于用戶的協(xié)同過濾推薦算法代碼示例,具有一定參考價值,需要的朋友可以了解下。2017-11-11Spring在多線程環(huán)境下如何確保事務一致性問題詳解
這篇文章主要介紹了Spring在多線程環(huán)境下如何確保事務一致性問題詳解,說到異步執(zhí)行,很多小伙伴首先想到Spring中提供的@Async注解,但是Spring提供的異步執(zhí)行任務能力并不足以解決我們當前的需求,需要的朋友可以參考下2023-11-11