出去打工和儿子租房
  • 性能測試常見故障和解決思路

    2022-01-10 13:50發布

    一、性能問題分析流程

    1、查看服務器的CPU、內存 、負載等情況,包括應用服務器和數據庫服務器

    2、查看數據庫健康狀態,數據庫死鎖、連接池不釋放

    3、查看項目日志(查看無報錯現象)

    4、查看jvmgc等情況

    二、內存溢出

    (一)堆內存溢出

    現象:

    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)通過JProfilerCPU 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、頁交換等)。

    (六)壓力機

    比如JmeterLoadrunner,單機負載能力有限,如果需要模擬的用戶請求數超過其負載極限,也會間接影響TPS(這個時候就需要進行分布式壓測來解決其單機負載的問題)。

    (七)業務邏輯

    業務解耦度較低,較為復雜,整個事務處理線被拉長也會導致TPS上不去。

    (八)系統架構

    比如是否有緩存服務,緩存服務器配置,緩存命中率、緩存穿透以及緩存過期等,都會影響到測試結果。

     

     

     



    出去打工和儿子租房