我一時興起對測試環境的服務在進行壓測的時候發現瞬時併發量居然不到三十就掛了.
我通過jstack導出內存線程發現很多請求線程在處理,因爲是併發壓測這很正常啊,沒發現有死鎖的情況.
然後我通過jstat -gc指令查看時發現jvm各區域的內存都滿了,並且在不停的執行Full GC
我使用過jmap指令將內存快照導出,然後用MAT工具打開
可以看到內存被兩種對象類型吃滿,我去看一下Tree
通過潛堆和深堆的大小判斷很明顯最大的其實是byte,
展開org.apache.coyote.http11.Http11OutputBuffer對象可以驗證:
java.nio.HeapByteBuffer中的數據就是上邊的byte
但是這些對象都是數據tomcat裏的呀,網上查了一下沒有結果.
我展開看開一下對象下的引用
通過類名看到是headerBuffer,還有output字眼,猜測這應該就是響應頭的緩衝區,
去看一下byte的內容
確定了這就是請求返回的頭信息並且不包含消息體,剩下的都是000也就是空內容.
就是請求返回頭的數據緩衝區過大導致.而且屬於tomcat.
但項目用的是SpringBoot內置的Tomat,按理不會有這種問題.
當時沒解決,線上環境是增大內存以保證服務正常,好在我們的系統瞬時併發並不高.
直到最近我在搭建項目監控平臺時改項目配置的時候看到這項配置
server:
port: 30001
max-http-header-size: 10000000
http-header-size?10000000?
這個名字和數值怎麼和我之前看到的byte名字和大小一致,都是header=10M
看了一下git提交記錄,這是我入職之前的人提交的而且沒人認識,commit寫的是用於加快XXX的速度.
我點配置進去看了一下默認是0,也就是不配是可以的.於是我就重新做了一下壓測.
確定了刪除這行配置項目併發已經恢復正常,不會出現內存溢出問題.