1. 程式人生 > >spring boot + embed tomcat + standalone jar的記憶體洩露問題

spring boot + embed tomcat + standalone jar的記憶體洩露問題

前一陣遇到了一個很坑的記憶體洩露問題,記錄於此:

有個專案採用spring cloud重構後,部署到線上(其中有一個介面,大概每天呼叫量在1千萬次左右),發現zabbix監控裡,linux的可用記憶體一直持續下降,每次重啟後,大概能撐1天,就算業務高峰過去了,記憶體也不見回收,曲線圖如下:

點選看原圖

發生故障時,用top -m 看java程序佔用的記憶體並不算高,而且spring boot的acurator端點監控,以及jvm的記憶體監控都在正常值範圍內,剛開始懷疑是jvm引數設定不合理,調整了G1垃圾收集器各種引數組合,沒有明顯效果,然後嘗試換回CMS收集器,再折騰了幾天,仍然如此。用dump匯出來分析,執行緒數、大物件啥的都不高,遂懷疑是spring cloud的坑。

攀牆出去google了下,無意搜尋" spring boot memory leak",發現有些人遇到了類似的問題,共同點都是embed tomcat + standalone jar執行方式,於是懷著試一試的心理,把容器換成了undertow,居然穩定了!

點選看原圖

附,更換方法:

    compile('org.springframework.boot:spring-boot-starter-web') {
        exclude module: "spring-boot-starter-tomcat"
    }
    compile('org.springframework.boot:spring-boot-starter-undertow')  

注:其它jar包也有可能隱式依賴了tomcat,保險起見最好加一個全域性的排除處理

    configurations {
        all*.exclude group: "org.springframework.boot", module: "spring-boot-starter-tomcat"
    }