1. 程式人生 > >性能測試遭遇TPS抖動問題

性能測試遭遇TPS抖動問題

比較 服務 ava pla 由於 徹底 壓測 current 基本上

目前性能測試組正在對獨立秒殺進行性能壓測,性能抖動特別厲害。

技術分享圖片

由於獨立秒殺的接口大多數是經過volicity渲染過的頁面和數據的整合,所以在壓測的時候有很多volicity的錯誤。初步判定,感覺是volicity的性能問題才導致的。但是通過排查volicity發現,此版本沒有網傳的性能問題,而且代碼層面上也沒見到有過多的性能問題點。

之後通過查看jvm的堆內內存才發現,老年代的內存無法釋放,總是會經過很長一段時間,大概三十四分鐘後才會釋放。感覺很奇怪:

技術分享圖片

從上圖可以看到,堆內內存漲上去後,基本上就下不來了, 這些沒釋放的內存,基本上都在老年代。初步判定為jvm堆內內存要麽有大對象,要麽什麽東西一直持有,並未釋放。

之後從服務器上dump數據下來,然後通過mat加載後,得到的分析如下:

技術分享圖片

可以看到,系統中,有一個ConcurrentHashMap的容器裏面,貌似對每個http請求,都做了一次緩存。考慮到目前做的是壓測,那麽也就是說瞬間湧入千萬級別的請求也不為過,ConcurrentHashMap的體積在很短的時間就會暴漲,勢必會帶來頻繁的gc問題。如果只是保存http請求狀態,為什麽http請求完畢,不會釋放呢?

帶著疑問去應用裏面進行排查,發現應用裏面根本沒有直接使用ConcurrentHashmap對象。那麽也就是說ConcurrentHashmap對象也許是存在什麽jar包裏面了。經過排查jar包,也沒發現什麽地方使用concurrenthashmap,頓時陷入了死局。

後來,壓測組發來一篇文章:壓力測試中JVM內存暴漲原因分析實戰, 看完文章,和我的遭遇非常一致,聯想到目前壓測直接使用ip+端口壓測,直接打到tomcat上進行壓測,而且接口返回數據都是經過velocity渲染的模板和數據組合,是有前端頁面的。所以說,按照文章中的說法,應該是tomcat對每一個進來的請求都會將狀態會話保持放到ConcurrentHashmap中導致的,而且這個狀態會話保持默認30分鐘後過期,這也是為啥GC一直下不來的原因了。

為了印證此說法,按照此文的建議, Memory Fully utilized by Java ConcurrentHashMap (under Tomcat),在web.xml中設置session過期時間為1分鐘:

<session-config>
    <session-timeout>1</session-timeout>
</session-config>

之後修改代碼,上預發,然後讓壓力機單壓預發這臺機器,可以看到堆內存回收如下:

技術分享圖片

可以看到當堆內存打到極高點後,jvm很快進行了一次回收,而且此次回收比較徹底。

驗證完畢,看來是這個原因。希望對你有幫助。

性能測試遭遇TPS抖動問題