一、性能問題分析流程
1、查看服務器的CPU、內存 、負載等情況,包括應用服務器和數據庫服務器
2、查看數據庫健康狀態,數據庫死鎖、連接池不釋放
3、查看項目日志(查看無報錯現象)
4、查看jvm的gc等情況
二、內存溢出
(一)堆內存溢出
現象:
(1)壓測執行一段時間后,系統處理能力下降。這時用JConsole、JVisualVM等工具連上服務器查看GC情況,每次GC回收都不徹底并且可用堆內存越來越少。
(2)壓測持續下去,最終在日志中有報錯信息:java.lang.OutOfMemoryError.Java heap space。
排查手段:
(1)使用jmap -histo pid > test.txt命令將堆內存使用情況保存到test.txt文件中,打開文件查看排在前50的類中有沒有熟悉的或者是公司標注的類名,如果有則高度懷疑內存泄漏是這個類導致的。
(2)如果沒有,則使用命令:jmap -dump:live,format=b,file=test.dump pid生成test.dump文件,然后使用MAT進行分析。
(3)如果懷疑是內存泄漏,也可以使用JProfiler連上服務器在開始跑壓測,運行一段時間后點擊“Mark Current Values”,后續的運行就會顯示增量,這時執行一下GC,觀察哪個類沒有徹底回收,基本就可以判斷是這個類導致的內存泄漏。
解決方式:
優化代碼,對象使用完畢,需要置成null。
(二)永久代/方法區溢出
現象:
壓測執行一段時間后,日志中有報錯信息:java.lang.OutOfMemoryError: PermGen space。
產生原因:
由于類、方法描述、字段描述、常量池、訪問修飾符等一些靜態變量太多,將持久代占滿導致持久代溢出。
解決方法:
修改JVM參數,將XX:MaxPermSize參數調大。盡量減少靜態變量。
(三)棧內存溢出
現象:
壓測執行一段時間后,日志中有報錯信息:java.lang.StackOverflowError。
產生原因:
線程請求的棧深度大于虛擬機所允許的最大深度,遞歸沒返回,戒者循環調用造成。
解決方法:
修改JVM參數,將Xss參數改大,增加棧內存。棧內存溢出一定是做批量操作引起的,減少批處理數據量。
(四)系統內存溢出
現象:
壓測執行一段時間后,日志中有報錯信息:java.lang.OutOfMemoryError: unable to create new native thread。
產生原因:
操作系統沒有足夠的資源來產生返個線程造成的。系統創建線程時,除了要在Java堆中分配內存外,操作系統本身也需要分配資源來創建線程。
因此,當線程數量達到一定程度以后,堆中或許還有空間,但是操作系統分配不出資源來了,就出現這個異常了。
解決方法:
(1)減少堆內存
(2)減少線程數量
(3)如果線程數量不能減少,則減少每個線程的堆棧大小,通過-Xss減小單個線程大小,以便能生產更多的線程。
三、CPU過高
(一)us cpu過高
現象:
壓測過程中,使用top命令查看系統資源占用情況,us cpu過高,超過50%以上。
排查手段:
(1)使用top命令是哪個進程消耗CPU高
(2)再找到CPU消耗高的線程:top -H -p 進程號
(3)把線程號轉換成16進制:printf "%x\n" 線程號
(4)再用jstack命令分析這個線程是在干什么:jstack 進程號 | grep 16進制的線程號
(5)通過JProfiler的CPU Views視圖的層層分析,可以清楚的找到造成CPU高的原因
(二)Sy cpu過高
現象:
壓測過程中,使用top命令查看系統資源占用情況,sy cpu過高,超過50%以上。
排查手段:
(1)首先查看磁盤繁忙程度、磁盤的隊列(iostat、nmon)
(2)如果磁盤沒有問題,則使用strace查看系統內核調用情況
四、TPS上不去
(一)網絡帶寬
在壓力測試中,有時候要模擬大量的用戶請求,如果單位時間內傳遞的數據包過大,超過了帶寬的傳輸能力,那么就會造成網絡資源競爭,間接導致服務端接收到的請求數達不到服務端的處理能力上限。
(二)連接池
最大連接數太少,造成請求等待。連接池一般分為服務器中間件連接池(比如Tomcat)和數據庫連接池(或者理解為最大允許連接數也行)。
(三)垃圾回收機制
從常見的應用服務器來說,比如Tomcat,如果堆內存設置比較小,就會造成新生代的Eden區頻繁的進行Young GC,老年代的Full GC也回收較頻繁,那么對TPS也是有一定影響的,因為垃圾回收時通常會暫停所有線程的工作。
(四)數據庫
高并發情況下,如果請求數據需要寫入數據庫,且需要寫入多個表的時候,如果數據庫的最大連接數不夠,或者寫入數據的SQL沒有索引沒有綁定變量,抑或沒有主從分離、讀寫分離等,就會導致數據庫事務處理過慢,影響到TPS。
(五)硬件資源
包括CPU(配置、使用率等)、內存(占用率等)、磁盤(I/O、頁交換等)。
(六)壓力機
比如Jmeter和Loadrunner,單機負載能力有限,如果需要模擬的用戶請求數超過其負載極限,也會間接影響TPS(這個時候就需要進行分布式壓測來解決其單機負載的問題)。
(七)業務邏輯
業務解耦度較低,較為復雜,整個事務處理線被拉長也會導致TPS上不去。
(八)系統架構
比如是否有緩存服務,緩存服務器配置,緩存命中率、緩存穿透以及緩存過期等,都會影響到測試結果。