記一次線下問題排查 SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@21db37de] was not regi...

????自從項(xiàng)目從PSSql數(shù)據(jù)庫(kù)切換到mysql后,時(shí)長(zhǎng)會(huì)出現(xiàn) SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@21db37de] was not registered for synchronization because synchronization is not active。所有頁面卡頓,服務(wù)基本就掛了,本以為是偶爾事件,結(jié)果暴力重啟后,一段時(shí)間再次出現(xiàn)了。頁面出現(xiàn)卡頓,一開始就覺得應(yīng)該是線程死鎖,jvm內(nèi)存撐滿,導(dǎo)致GC頻繁。

所以,首先檢查jvm。。。

查看cpu情況,top -Hp pid

如圖所示,cpu最大才占用2%,內(nèi)存最大也才5%,所以明顯不是線程死鎖導(dǎo)致的。

繼續(xù)排查。。。

查看gc情況,jstat -gc pid

如圖,即便Eden區(qū)和from區(qū)數(shù)據(jù)滿了,但總體的GC情況還是可控的,所以也不是這里的問題。

導(dǎo)出dump文件, jmap -dump:format=b,file=heap.hprof 20210,使用jprofiler查看當(dāng)前創(chuàng)建對(duì)象數(shù)。

如圖,當(dāng)前存在的對(duì)象,最多的也只有13kb,所以不太可能是內(nèi)存問題,但很明顯jvm內(nèi)存需要增加了。。。

至此,確認(rèn)不是jvm問題,開始排除mysql數(shù)據(jù)庫(kù)問題。仔細(xì)分析接口請(qǐng)求,發(fā)現(xiàn)

Creating a new SqlSession

SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@30579c64] was not registered for synchronization because synchronization is not active

JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5ad7e3ac] will not be managed by Spring

懷疑是不是請(qǐng)求連接數(shù)據(jù)庫(kù),但連接沒有被釋放。查看durid連接池的配置。

所有參數(shù)都是默認(rèn)的。上網(wǎng)查找druid參數(shù)詳解,參考連接 https://blog.csdn.net/weixin_33924770/article/details/94117616

數(shù)據(jù)庫(kù)連接池在初始化的時(shí)候會(huì)創(chuàng)建initialSize個(gè)連接,當(dāng)有數(shù)據(jù)庫(kù)操作時(shí),會(huì)從池中取出一個(gè)連接;  如果當(dāng)前池中正在使用的連接數(shù)等于maxActive,則會(huì)等待一段時(shí)間,等待其他操作釋放掉某一個(gè)連接,如果這個(gè)等待時(shí)間超過了maxWait,則會(huì)報(bào)錯(cuò)。默認(rèn)值并沒有設(shè)置maxWait,所以估計(jì)它會(huì)一直等待下去,導(dǎo)致頁面卡頓,一直刷不出來。

連接池配置文件中添加參數(shù):

initialSize: 20

min-idle: 20

max-active: 100

max-wait: 3000

time-between-eviction-runs-millis: 60000

至此的確不在出現(xiàn)頁面卡頓這個(gè)問題了。

?但新的問題來了,只要服務(wù)運(yùn)行一段時(shí)間,又會(huì)出現(xiàn)報(bào)錯(cuò)。。。。

這種報(bào)錯(cuò),表明數(shù)據(jù)庫(kù)連接太多,已經(jīng)將連接池中的連接撐滿,導(dǎo)致有再次請(qǐng)求是等待超時(shí),報(bào)錯(cuò)。。。。

這就奇怪了,難道是druid,沒有管理連接池嗎??難道請(qǐng)求一次,就會(huì)新建一個(gè)新的連接???


查看數(shù)據(jù)庫(kù)

數(shù)據(jù)庫(kù)最大連接數(shù)

show variables like ‘%max_connections%’;

當(dāng)前連接數(shù)

show full processlist;

果然發(fā)現(xiàn)每請(qǐng)求一次,就會(huì)增加一條連接數(shù)。。。

排查代碼。。。

最后發(fā)現(xiàn)有人在代碼里手寫開啟數(shù)據(jù)庫(kù)連接,然后沒有關(guān)閉,也沒有拋出異常。結(jié)果我們沒有捕獲到異常,在完全不知情的情況下,花了幾天時(shí)間排查問題。。。。。。。。。


????這里做一個(gè)問題排查總結(jié),這一次雖然是代碼上的問題,但從問題出現(xiàn),與原因分析,對(duì)于一個(gè)完全沒有jvm故障排查經(jīng)驗(yàn)的人來說,是一份很好的經(jīng)歷,雖然過程曲折,到從jvm,數(shù)據(jù)庫(kù),到druid連接池配置,都是一次難得的回憶。。。。。


ps:我們也曾經(jīng)調(diào)試過druid配置:removeAbandoned?如果連接泄露,是否需要回收泄露的連接,但也不是這個(gè)原因,所以的原因都分析過了,再重新看代碼時(shí)就會(huì)充滿懷疑。。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容