天天看點

線上性能問題初步排查方法

引言

有時候有很多問題隻有線上上或者預發環境才能發現,而線上又不能Debug,是以線上問題定位就隻能看日志,系統狀态和Dump線程,本文隻是簡單的介紹一些常用的工具,幫助定位線上問題。

問題定位

1: 首先使用TOP指令檢視每個程序的情況,顯示如下:

我們的程式是Java應用,是以隻需要關注COMMAND是Java的性能資料,COMMAND表示啟動目前程序的指令,在Java程序這一行裡可以看到CPU使用率是300%,不用擔心,這個是目前機器所有核加在一起的CPU使用率。      

2: 再使用Top的互動指令數字1檢視每個CPU的性能資料。

指令行顯示了CPU4,說明這是一個5核的虛拟機,平均每個CPU使用率在60%以上。如果這裡顯示CPU使用率100%,則很有可能程式裡寫了一個死循環。這些參數的含義,可以對比下表:      

3: 使用Top的互動指令H檢視每個線程的性能資訊。

在這裡可能會出現三種情況:      
  1. 如果是第一種情況,也有可能是GC造成,我們可以用jstat指令看下GC情況,看看是不是因為持久代或年老代滿了,産生Full GC,導緻CPU使用率持續飙高,指令如下。
    我們還可以把線程Dump下來,看看究竟是哪個線程,執行什麼代碼造成的CPU使用率高。執行以下指令,把線程dump到檔案dump17裡。      
    sudo -u admin /opt/java/bin/jstack  31177 > /home/tengfei.fangtf/dump17
          
    dump出來内容的類似下面這段:
    "http-0.0.0.0-7001-97" daemon prio=10 tid=0x000000004f6a8000 nid=0x555e in Object.wait() [0x0000000052423000]
       java.lang.Thread.State: WAITING (on object monitor)
            at java.lang.Object.wait(Native Method)
            - waiting on  (a org.apache.tomcat.util.net.AprEndpoint$Worker)
            at java.lang.Object.wait(Object.java:485)
            at org.apache.tomcat.util.net.AprEndpoint$Worker.await(AprEndpoint.java:1464)
            - locked  (a org.apache.tomcat.util.net.AprEndpoint$Worker)
            at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1489)
            at java.lang.Thread.run(Thread.java:662)
          
    dump出來的線程ID(nid)是十六進制的,而我們用TOP指令看到的線程ID是10進制的,是以我們要printf指令轉換一下進制。然後用16進制的ID去dump裡找到對應的線程。
    優化實戰      
    1:檢視下TCP連接配接狀态,建立了800多個連接配接,需要盡量降低ESTABLISHED。
    2:用jstack dump看看這些線程都在做什麼。      
    3:統計下所有線程分别處于什麼狀态,發現大量線程處于WAITING(onobjectmonitor)狀态      
    4:檢視處于WAITING(onobjectmonitor)的線程資訊,主要是jboss的工作線程在await。      
    "http-0.0.0.0-7001-97" daemon prio=10 tid=0x000000004f6a8000 nid=0x555e in Object.wait() [0x0000000052423000]
     java.lang.Thread.State: WAITING (on object monitor)
     at java.lang.Object.wait(Native Method)
     - waiting on <0x00000007969b2280> (a org.apache.tomcat.util.net.AprEndpoint$Worker)
     at java.lang.Object.wait(Object.java:485)
     at org.apache.tomcat.util.net.AprEndpoint$Worker.await(AprEndpoint.java:1464)
     - locked <0x00000007969b2280> (a org.apache.tomcat.util.net.AprEndpoint$Worker)
     at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1489)
     at java.lang.Thread.run(Thread.java:662)      

    5:找到jboss的線程配置資訊,将maxThreads降低到100

    6:重新開機jboss,再dump線程資訊,然後統計,WAITING(onobjectmonitor)的線程減少了170。

    其他指令      
    • 檢視CPU資訊 cat /proc/cpuinfo
    • 檢視記憶體資訊 cat /proc/meminfo
    • 檢視Java線程數 ps -eLf | grep java -c
    • 檢視linux系統裡打開檔案描述符的最大值 ulimit -u
    • 找到日志裡TOP10的異常:grep ‘Exception’ /home/admin/logs/XX.log |awk -F':|,’ ‘{print $2}’|sort |uniq -c |sort -nr|head -10,找到之後可以再用-A 2 -B 2,看定位出日志的前面2行和後面兩行。

關注90後夢想大師,夢想從未止步.