springboot打包成war發佈的坑

大家先來看下面兩張圖,一樣的接口,查詢時間波動很大:

 

 

 

這個問題糾纏很久了,之前我做btr-open-web開放平臺的時候就有遇到,後面想去查一下,但是後面開放平臺沒人用,就沒動力去處理了。接着btr-srm-web也有這個問題,當時吳通大佬沒找出來,我看到跟我之前遇到的一樣。然後測試跟產品也反饋大概半年了,之前查了一下,沒查到放棄了,也都能湊合用,一會纔會慢一下,內部用,也一直沒處理,拖到現在。

 

思考:偶爾查詢慢的問題,一開始懷疑的連接池的問題,獲取連接慢,慢慢加大最小連接數,也還是不行。

最後爲了驗證是不是連接池的問題,我把最小、最大、初始化設置成一樣。然後發現還是一樣,想想也沒道理,新建連接怎麼也不用10幾秒。

實在沒辦法了,把接口時間打印出來,把所有日誌改成debug,下面的圖就是我截取的有問題的部分。找到時間長的,原來發現了不知道爲啥要加載類,要查找類。以爲是BeanUtils工具類的問題,然後我去掉了,然後繼續請求,還是有慢的。

然後我又去看日誌(下圖),發現沒有使用這個。然後再看,有點奇怪,看起來要重新classload類進去?這時候不懂了,按道理不是一開始加載進去了嗎?

 

就去谷歌一下。因爲我發現兩個項目都是spingboot,我猜是它,所以搜了spingboot+findClass ClassNotFoundException,沒想到還真的搜到了。有個人遇到jsp的問題,然後也是打包成war(我們公司的springboot也都是打包成war)包,然後也是找不到類,也是慢,我就看了一下,下面去這個文章的截圖。

 

裏面有springboot項目的一個issues,講的就是類加載慢的問題,後面這個是springboot成員給的方案,剛好直接用,很好的解決了,我截一下主要的給大家看看

 

 

 

 

 

具體原因(暫無一步一步跟蹤源碼,看兩種解決方案總結出來):

 

根據上面的上的討論,因爲embeded tomcat默認會開啓reloadable熱加載,默認每超過15秒都會嘗試重新加載。這也大概解釋了爲什麼日誌顯示加載不到還是能正常跑,估計首次啓動的時候是通過spring boot的類加載成功了,後面對於war包,springboot找資源的時候,應該是沒考慮這樣的情況,tomcat的熱加載不支持的兩層嵌套就會一直失敗,然後導致加載慢。

 

具體大家可以直接看看兩種解決方案,裏面有詳細對話信息,鏈接我發出來了。

 

問題處理:

 

springboot 1.0解決方案:不允許自動重新load類,按道理也沒必要。

 

springboot 2.0解決方案:直接重寫查找lib的方法,兼容springboot打包成war的情況,建議第二種。
https://github.com/spring-projects/spring-boot/issues/16471

 

 

因爲我們是springboot 2.x,所以我直接使用方案2,然後點了好久,都沒有慢的,沒有發現這個問題了。大家可以去新商家平臺操作一下,除了33環境(我發了我的分支),其它分支之前的都是時不時會有接口10秒左右。

http://docker33-srm.qipeipu.net/#/http://docker34-srm.qipeipu.net/#/,可以對比一下這兩個環境,大家去多點點就發現了。

 

總體思路:

第一個方案是不給tomcat自動加載,把參數設置爲false

第二是springboot做了擴展,支持了war資源問題的加載,然後就正常使用了。

 

 

 

下面就是擴展類,加強了war的資源lib的處理。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章