1. 程式人生 > >線上應用故障排查之一:高CPU佔用

線上應用故障排查之一:高CPU佔用

一個應用佔用CPU很高,除了確實是計算密集型應用之外,通常原因都是出現了死迴圈。

以我們最近出現的一個實際故障為例,介紹怎麼定位和解決這類問題。

根據top命令,發現PID為28555的Java程序佔用CPU高達200%,出現故障。

通過ps aux | grep PID命令,可以進一步確定是tomcat程序出現了問題。但是,怎麼定位到具體執行緒或者程式碼呢?

首先顯示執行緒列表:

ps -mp pid -o THREAD,tid,time

找到了耗時最高的執行緒28802,佔用CPU時間快兩個小時了!

其次將需要的執行緒ID轉換為16進位制格式:

printf "%x\n" tid

最後列印執行緒的堆疊資訊:

jstack pid |grep tid -A 30

找到出現問題的程式碼了!

現在來分析下具體的程式碼:ShortSocketIO.readBytes(ShortSocketIO.java:106)

ShortSocketIO是應用封裝的一個用短連線Socket通訊的工具類。readBytes函式的程式碼如下:

public byte[] readBytes(int length) throws IOException {

    if ((this.socket == null) || (!this.socket.isConnected())) {

        throw new IOException("++++ attempting to read from closed socket");

    }

    byte[] result = null;

    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    if (this.recIndex >= length) {

           bos.write(this.recBuf, 0, length);

           byte[] newBuf = new byte[this.recBufSize];

           if (this.recIndex > length) {

               System.arraycopy(this.recBuf, length, newBuf, 0, this.recIndex - length);

           }

           this.recBuf = newBuf;

           this.recIndex -= length;

    } else {

           int totalread = length;

           if (this.recIndex > 0) {

                totalread -= this.recIndex;

                bos.write(this.recBuf, 0, this.recIndex);

                this.recBuf = new byte[this.recBufSize];

                this.recIndex = 0;

    }

    int readCount = 0;

    while (totalread > 0) {

         if ((readCount = this.in.read(this.recBuf)) > 0) {

                if (totalread > readCount) {

                      bos.write(this.recBuf, 0, readCount);

                      this.recBuf = new byte[this.recBufSize];

                      this.recIndex = 0;

               } else {

                     bos.write(this.recBuf, 0, totalread);

                     byte[] newBuf = new byte[this.recBufSize];

                     System.arraycopy(this.recBuf, totalread, newBuf, 0, readCount - totalread);

                     this.recBuf = newBuf;

                     this.recIndex = (readCount - totalread);

             }

             totalread -= readCount;

        }

   }

}

問題就出在標紅的程式碼部分。如果this.in.read()返回的資料小於等於0時,迴圈就一直進行下去了。而這種情況在網路擁塞的時候是可能發生的。

至於具體怎麼修改就看業務邏輯應該怎麼對待這種特殊情況了。

最後,總結下排查CPU故障的方法和技巧有哪些:

1、top命令:Linux命令。可以檢視實時的CPU使用情況。也可以檢視最近一段時間的CPU使用情況。

2、PS命令:Linux命令。強大的程序狀態監控命令。可以檢視程序以及程序中執行緒的當前CPU使用情況。屬於當前狀態的取樣資料。

3、jstack:Java提供的命令。可以檢視某個程序的當前執行緒棧執行情況。根據這個命令的輸出可以定位某個程序的所有執行緒的當前執行狀態、執行程式碼,以及是否死鎖等等。

4、pstack:Linux命令。可以檢視某個程序的當前執行緒棧執行情況。

http://binma85.iteye.com/blog/778986

開門見山,本文將簡述如何使用java thread dump來分析CPU高使用率以及執行緒死鎖問題。 
一般java thread dump用於web開發中分析web容器或是應用伺服器的效能問題還是比較常用並有效的。常用的入門級web容器Tomcat,以及高級別的jboss、websphere、weblogic等的效能調優問題都可以使用java thread dump來分析。 
首先,闡述一下thread dump常用來解決的是何種問題 
(1)高CPU使用 
(2)執行緒死鎖 
其次,使用步驟[以JBOSS為例] 
1..get thread dump log 
(1)找到應用程式所在的程序號,命令如下 

  1. ps aux |grep 'jboss' | grep 'java'  

、 
獲取需要的PID 
(2)執行sudo kill -3 PID獲取thread dump log(PID是第一步獲取)。 
注意:在不同的linux環境下執行輸出的日誌的地方可能不同。在IBM的PowerPC小型機上的linux上執行kill -3 pid會在工作目錄下產生類似javacore.20100409.161739.7614.0001.txt的檔案。JBOSS預設環境下,thread dump log輸出到jboss console,所以thread dump資訊會輸出到個人定義的控制檯列印log中。 
部分示例如下所以: 

引用
2010-10-08 20:27:42 
Full thread dump Java HotSpot(TM) Server VM (16.3-b01 mixed mode): 

"http-182.50.0.138-8084-6" daemon prio=10 tid=0x08ce5000 nid=0x6a4c in Object.wait() [0x87b5c000] 
   java.lang.Thread.State: WAITING (on object monitor) 
at java.lang.Object.wait(Native Method) 
- waiting on <0x95eb81b0> (a org.apache.tomcat.util.net.JIoEndpoint$Worker) 
at java.lang.Object.wait(Object.java:485) 
at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:415) 
- locked <0x95eb81b0> (a org.apache.tomcat.util.net.JIoEndpoint$Worker) 
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:441) 
at java.lang.Thread.run(Thread.java:619) 

"http-182.50.0.138-8084-5" daemon prio=10 tid=0x08c2e000 nid=0x6a4b in Object.wait() [0x87bad000] 
   java.lang.Thread.State: WAITING (on object monitor) 
at java.lang.Object.wait(Native Method) 
- waiting on <0x95ed0600> (a org.apache.tomcat.util.net.JIoEndpoint$Worker) 
at java.lang.Object.wait(Object.java:485) 
at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:415) 
- locked <0x95ed0600> (a org.apache.tomcat.util.net.JIoEndpoint$Worker) 
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:441) 
at java.lang.Thread.run(Thread.java:619) 

"ajp-127.0.0.1-8009-Acceptor-0" daemon prio=10 tid=0x894de800 nid=0x6a45 runnable [0x881f3000] 
   java.lang.Thread.State: RUNNABLE 
at java.net.PlainSocketImpl.socketAccept(Native Method) 
at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:390) 
- locked <0x949c1288> (a java.net.SocksSocketImpl) 
at java.net.ServerSocket.implAccept(ServerSocket.java:453) 
at java.net.ServerSocket.accept(ServerSocket.java:421) 
at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:61)
at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:309) 
at java.lang.Thread.run(Thread.java:619) 

DefaultQuartzScheduler_QuartzSchedulerThread" prio=10 tid=0x8a460800 nid=0x6a38 sleeping[0x88818000] 
   java.lang.Thread.State: TIMED_WAITING (sleeping) 
at java.lang.Thread.sleep(Native Method) 
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:394) 



(3)獲取執行緒資訊 
使用上面的ps或者使用top命令也可以。獲取的執行緒資訊如下所示: 

引用
27143 root      20   0  780m 376m  11m S   17 11.5   2:56.48 java                                                                   
4839 root      20   0  778m 162m  11m S   10  5.0   1717:03 java                                                                   
5049 root      20   0  764m 147m  11m S    4  4.5   1744:06 java                                                                   
    1 root      20   0  2100  720  624 S    0  0.0   0:28.08 init                                                                   
    2 root      15  -5     0    0    0 S    0  0.0   0:00.00 kthreadd                                                               
    3 root      RT  -5     0    0    0 S    0  0.0   0:00.44 migration/0   


第一列是十進位制PID,需要轉化為16進位制後才能和thread dump資訊對應。 
2.分析thread dump資訊[不在列舉示例,只講思想] 
(1)分析高CPU使用執行緒的thread dump資訊,查詢那些程式碼導致高CPU使用。 
(2)執行緒死鎖 
    a.為了發現執行緒動態變化,需要多次做thread dump,每次間隔10-30s為佳. 
    b.執行緒狀態用 runnable(正在執行)、waiting for monitor(主動等待)、waiting for monitor entry(死鎖)。所以我們最多的是關注runnable和entry型別的執行緒。 
一種典型的死鎖是在server端多個應用同時使用同一個jboss資源,這時候需要將多個應用分不到不用的佇列中。

參考文獻:

http://www.51testing.com/?uid-188107-action-viewspace-itemid-226468

1.分析記憶體的工具

使用Memory Analyzer tool(MAT)分析記憶體洩漏(二)    使用前需要在linux上通過jmap -dump:format=b,file={$filename} ${pid}方式將heap的記憶體快照檔案給dump出來,然後就可以通過上面的MAT進行分析了。注意dump出來的檔名要以bin作為字尾名不然可能識別不了哦.

例如: jmap -dump:format=b,file=a.bin 2298

2.執行緒狀態分析

"exec-613" Id=713 in BLOCKED on [email protected] owned by tomcatThreadPool-exec-553 Id=623

"exec-553" Id=623 in TIMED_WAITING on [email protected] at java.lang.Object.wait(Native Method)

"NioProcessor-1" Id=700 in RUNNABLE (running in native) at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:215) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)

"RMI TCP Connection(8)-172.25.3.81" Id=698 in RUNNABLE at sun.management.ThreadImpl.getThreadInfo0(Native Method) at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:145) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597)

RUNNABLE(正在執行的,消耗cpu)  TIMED_WAITING(等待被分配到cpu執行的,現在不消耗cpu) BLOCKED(被阻塞,在阻塞解除前不能被分配cpu執行,現在不消耗cpu)

exec-613佔用了鎖,exec-553需要的鎖被exec-613佔用無法執行處於blocked狀態.

NioProcessor-1正在執行,並且他的方法在呼叫native方法.

RMI TCP Connection(8)-172.25.3.81正在執行.

(一) jinfo   jinfo列印一個給定的Java程序或核心檔案或一個遠端除錯伺服器的Java配置資訊。配置資訊包括Java系統屬性和JVM命令列標誌(更多資訊,請參考《jinfo-Configuration Info》)。   (二) jmap   jmap:如果這個工具不使用任何選項(除了pid或core選項)執行,那麼它顯示類似於Solaris的pmap工具所輸出的資訊。這個工具支援針對Java堆可觀察性的若干其它選項。   在Java SE 6平臺中,新加入了一個-dump選項。這樣可以使jmap能夠把Java堆資訊複製到一個檔案中,然後我們可以使用新的jhat命令(見下面一節)來分析它。   jmap -dump選項並不使用Solaris libproc來實現實時處理;而是,它運行當前正執行的JVM中的一小段程式碼,由此來實現堆複製。既然這種堆複製程式碼運行於JVM內部,那麼其速度是比較快的。堆複製的效果大致相當於實現一次"完全的GC"(對整個堆的垃圾收集),再加上把該堆的內容寫入到檔案中。實現堆複製的另外一種可能的思路是使用 gcore來進行核心複製並且執行"jmap -dump"(這與以"離線"方式執行的核心複製形成對照)。 

    可以輸出某個java程序記憶體內物件的情況,甚至可以將VM 中的heap,以二進位制輸出成文字。

[[email protected] ~]# jmap -histo 710 >mem.txt(可使用文字對比工具對比出GC回收了哪些物件) 該檔案中內容如: num #instances #bytes class name ---------------------------------------------- 4:  1202692  67350752 java.io.ObjectStreamClass$WeakClassKey
[[email protected] ~]#jmap -dump:format=b,file=mem.bin 710 (將該程序heap輸出到mem.bin檔案中,使用二進位制形式。該檔案可供其他 分析工具使用,如eclipse memory analyser) 注:jmap使用的時候jvm是處在假死狀態的,只能在服務癱瘓的時候為了解決問題來使用,否則會造成服務中斷

  (三) jstack   jstack等價於Solaris的pstack工具。jstack列印所有的Java執行緒的堆疊跟蹤資訊(可選地包括本機幀資訊),請參考《jstack-堆疊跟蹤》。關於鎖和死鎖的資訊也可以被列印,請參考java.util.concurrent locks。   top 時 H顯示執行緒情況   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                 29390 mqq       15   0 1696m 1.3g 8784 S  100 16.3   1:46.19 java                                                                    29889 mqq       16   0 1696m 1.3g 8784 S    6 16.3   1:23.26 java                                                                    29904 mqq       15   0 1696m 1.3g 8784 S    2 16.3   0:14.87 java                                                                    29849 mqq       15   0 1696m 1.3g 8784 S    1 16.3   0:14.68 java                                                                    29388 mqq       16   0 1696m 1.3g 8784 S    1 16.3   0:12.55 java                                                                    29850 mqq       15   0 1696m 1.3g 8784 S    1 16.3   0:15.26 java   其中執行緒29390轉換為16進製為0x72ce,可以查出對應比較耗時執行緒在做什麼 jstack 29364|grep -A10 72ce "Thread-2" prio=10 tid=0x00002aab0b603c00 nid=0x72ce runnable [0x000000004133b000..0x000000004133baa0]    java.lang.Thread.State: RUNNABLE         at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)         at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:215)         at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:65)         at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:69)         - locked <0x00002aaab2d972e8> (a sun.nio.ch.Util$1)         - locked <0x00002aaab2d972d0> (a java.util.Collections$UnmodifiableSet)         - locked <0x00002aaab2283470> (a sun.nio.ch.EPollSelectorImpl)         at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:80)         at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:84)
(四) jsadebugd   jsadebugd依附到一個Java程序或核心檔案並且擔當一個除錯伺服器的作用。遠端客戶,例如jstack、jmap和jinfo,都能夠通過Java RMI依附到該伺服器。   (五) jhat   jhat是一個Java堆複製瀏覽器。這個工具分析Java堆複製檔案(例如,由上面的 "jmap -dump"所產生的)。Jhat啟動一個允許堆中的物件在web瀏覽器中進行分析的web伺服器。這個工具並不是想用於應用系統中而是用於"離線"分析。"jhat工具是平HIDDEN立的",其意思是,它可以被用來觀察在任何平臺上所產生的堆複製。例如,我們有可能在Linux系統上使用jhat來觀察一個在Solaris OS上所產生的堆複製。
(六)jstat 查出gc情況

很強大的監視jvm記憶體工具,可用來檢視堆內各個部分的使用量,以及載入類的數量。使用時,需指定java程序號。
一般使用 -gcutil 檢視gc情況。
[[email protected] ~]# jstat -class 710(顯示載入class的數量,及所佔空間等資訊) Loaded  Bytes  Unloaded  Bytes     Time    11242 24450.0       41    65.8      30.25
jstat -compiler pid:顯示VM實時編譯的數量等資訊。
jstat -gc pid:可以顯示gc的資訊,檢視gc的次數及時間。其中最後五項,分別是young gc的次數,young gc的時間
,full gc的次數,full gc的時間,gc的總時間。
jstat -gccapacity pid:可以顯示VM記憶體中三代(young,old,perm)物件的使用和佔用大小,如:PGCMN顯示的是
最小perm的記憶體使用量,PGCMX顯示的是perm的記憶體最大使用量,PGC是當前新生成的perm記憶體佔用量,PC是當
前perm記憶體佔用量。

語法結構如下:jstat [Options] vmid [interval] [count]     Options — 選項,我們一般使用 -gcutil 檢視gc情況     vmid    — VM的程序號,即當前執行的java程序號     interval– 間隔時間,單位為秒或者毫秒     count   — 列印次數,如果預設則列印無數次       S0  — Heap上的 Survivor space 0 區已使用空間的百分比     S1  — Heap上的 Survivor space 1 區已使用空間的百分比     E   — Heap上的 Eden space 區已使用空間的百分比     O   — Heap上的 Old space 區已使用空間的百分比     P   — Perm space 區已使用空間的百分比     YGC — 從應用程式啟動到取樣時發生 Young GC 的次數     YGCT– 從應用程式啟動到取樣時 Young GC 所用的時間(單位秒)     FGC — 從應用程式啟動到取樣時發生 Full GC 的次數     FGCT– 從應用程式啟動到取樣時 Full GC 所用的時間(單位秒)     GCT — 從應用程式啟動到取樣時用於垃圾回收的總時間(單位秒)
    例項使用1:
[[email protected] bin]# jstat -gcutil 25444
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
 11.63   0.00   56.46  66.92  98.49 162    0.248    6      0.331    0.579
 
例項使用2:
[[email protected] bin]# jstat -gcutil 25444 1000 5
  S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT
 73.54   0.00  99.04  67.52  98.49    166    0.252     6    0.331    0.583
 73.54   0.00  99.04  67.52  98.49    166    0.252     6    0.331    0.583
 73.54   0.00  99.04  67.52  98.49    166    0.252     6    0.331    0.583
 73.54   0.00  99.04  67.52  98.49    166    0.252     6    0.331    0.583
 73.54   0.00  99.04  67.52  98.49    166    0.252     6    0.331    0.583

jps

    與ps命令類似,用來顯示本地的java 程序,檢視本地執行著幾個java應用,並顯示程序號。

[[email protected] ~]# jps(只顯示程序號) 23813 Jps 710 Bootstrap 792 Bootstrap
[[email protected] ~]# jps -v(顯示jvm引數) 23852 Jps -Denv.class.path=.:/usr/jdk1.6.0_21/lib/dt.jar:/usr/jdk1.6.0_21/lib/tools.jar -Dapplication.home=/usr/jdk1.6.0_21 -Xms8m 710 Bootstrap -Xms2048m -Xmx2048m -XX:NewRatio=2 -XX:PermSize=256M -XX:MaxPermSize=512M -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.util.logging.config.file=/root/zhusj/apache-tomcat-6.0.18_1/conf/logging.properties -Dcom.sun.management.jmxremote.port=8799 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.endorsed.dirs=/root/zhusj/apache-tomcat-6.0.18_1/endorsed -Dcatalina.base=/root/zhusj/apache-tomcat-6.0.18_1 -Dcatalina.home=/root/zhusj/apache-tomcat-6.0.18_1 -Djava.io.tmpdir=/root/zhusj/apache-tomcat-6.0.18_1/temp

sar : 既能收集系統 CPU 、硬碟網路裝置等動態資料,更能檢視二進位制資料檔案等。

用法:

sar [引數選項] t [n] [-o file] ( t 為取樣間隔秒,必須有, n 為取樣次數,可選,預設值 1 )

引數說明:

-A 顯示所有歷史資料,通過讀取/var/log/sar 目錄下的所有檔案,並把它們分門別類的顯示出來;  -b 通過裝置的I/O 中斷讀取設定的吞吐率;  -B 報告記憶體或虛擬記憶體交換統計;  -c 報告每秒建立的程序數;  -d 報告物理塊裝置(儲存裝置)的寫入、讀取之類的資訊,如果直觀一點,可以和p 引數共同使用,-dp  -f 從一個二進位制的資料檔案中讀取內容,比如sar -f filename ;  -n 分析網路裝置狀態的統計,後面可以接的引數有DEV 、EDEV 、NFS 、NFSD 、SOCK 等。比如-n DEV  -o 把統計資訊以二進位制格式寫入一個檔案,比如-o filename ;  -u 報告CPU 利用率的引數;  -P 報告每個處理器應用統計,用於多處理器機器,並且啟用SMP 核心才有效;  -p 顯示友好裝置名字,以方便檢視,也可以和-d 和-n 引數結合使用;

-r 記憶體和交換區佔用統計;  -t 這個選項對從檔案讀取資料有用,如果沒有這個引數,會以本地時間為標準讀出;  -v 報告inode, 檔案或其它 核心表的資源佔用資訊;  -w 報告系統交換活動的資訊; 每少交換資料的個數;  -W 報告系統交換活動吞吐資訊;  -x 用於監視程序的,在其後要指定程序的PID 值;  -X 用於監視程序的,但指定的應該是一個子程序ID ;

CPU利用率:

[[email protected] ~]#sar -u 1 5 Linux 2.6.18-53.el5 (B1943)  2011年01月13日

14時58分08秒     CPU     %user     %nice   %system   %iowait    %steal     %idle 14時58分09秒     all      0.00      0.00      0.00      0.00      0.00    100.00 14時58分10秒     all      0.50      0.00      0.00      0.00      0.00     99.50 14時58分11秒     all      0.00      0.00      0.00      0.00      0.00    100.00 14時58分12秒     all      0.00      0.00      0.00      0.00      0.00    100.00 14時58分13秒     all      0.00      0.00      0.00      0.00      0.00    100.00 Average:        all      0.10      0.00      0.00      0.00      0.00     99.90

%usr cpu 使用者模式下時間(百分比)  %sys cpu 系統模式下時間(百分比)

%nice 表示 CPU 在使用者層優先順序的百分比, 0 表示正常;  %iowait cpu 等待輸入 / 輸出完成(時間百分比)  %idle cpu 空閒時間(百分比)

將動態資訊寫入檔案中:

[[email protected] ~]#sar -u 1 5 > sar000.txt  [[email protected] ~]# cat sar000.txt

也可以輸出到一個二進位制的檔案中,然後通過 sar 來檢視;

[[email protected] ~]#sar -u 1 5 -o sar002  [[email protected] ~]# sar -f sar002

網路裝置的吞吐情況:

[[email protected] ~]#sar -n DEV 2 5 |grep eth0 15時04分12秒      eth0      6.97      1.00      0.54      0.07      0.00      0.00      0.00 15時04分14秒      eth0      7.50      1.50      0.71      0.16      0.00      0.00      0.00 15時04分16秒      eth0      6.00      1.50      0.43      0.16      0.00      0.00      0.00 15時04分18秒      eth0      7.50      1.50      0.58      0.16      0.00      0.00      0.00 15時04分20秒      eth0      7.50      1.50      0.50      0.16      0.00      0.00      0.00 Average:         eth0      7.09      1.40      0.55      0.14      0.00      0.00      0.00

IFACE:裝置名; rxpck/s:每秒收到的包; rxbyt/s:每秒收到的所有包的體積 txbyt/s:每秒傳輸的所有包的體積; rxcmp/s:每秒收到資料切割壓縮的包總數; txcmp/s:每秒傳輸的資料切割壓縮的包的總數; rxmcst/s:每秒收到的多點傳送的包。
iostat:用法:
iostat [ -c | -d ] [ -k ] [ -t ] [ -V ] [ -x [ device ] ] [ interval [ count ] ]> outputfile
其中, -c為彙報CPU的使用情況; -d為彙報磁碟的使用情況; -k表示每秒按kilobytes位元組顯示資料; -x可獲得更多資訊; interval指每次統計間隔的時間; count指按照這個時間間隔統計的次數。  
[[email protected] ~]# iostat -d -k -x Linux 2.6.18-53.el5 (B1943)  2011年01月13日 Device:          rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util sda                 0.02     4.10    0.11    1.77     2.11    23.45    27.24     0.00    1.15   0.63   0.12 rrqm/s:每秒這個裝置相關的讀取請求有多少被Merge了(當系統呼叫需要讀取資料的時候,VFS將請求發到各個FS,如果FS發現不同的讀取請求讀取的是相同Block的資料,FS會將這個請求合併Merge);
wrqm/s:每秒這個裝置相關的寫入請求有多少被Merge了。
rsec/s:每秒讀取的扇區數;
wsec/s:每秒寫入的扇區數。
r/s:The number of read requests that were issued to the device per second;
w/s:The number of write requests that were issued to the device per second;
await:每一個IO請求的處理的平均時間(單位是微秒)。這裡可以理解為IO的響應時間,一般地系統IO響應時間應該低於5ms,如果大於10ms就比較大了。
%util:在統計時間內所有處理IO時間,除以總共統計時間。例如,如果統計間隔1秒,該裝置有0.8秒在處理IO,而0.2秒閒置,那麼該裝置的%util = 0.8/1 = 80%,所以該引數暗示了裝置的繁忙程度。一般地,如果該引數是100% 表示裝置已經接近滿負荷運行了(當然如果是多磁碟,即使%util是100%,因為磁碟的併發能力,所以磁碟使用未必就到了瓶頸)。
[[email protected] ~]# iostat -d -k Linux 2.6.18-53.el5 (B1943)  2011年01月13日
Device:             tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn sda                1.88         2.11        23.45    1122861   12458568
tps:該裝置每秒的傳輸次數(Indicate the number of transfers per second that were issued to the device.)。“
一次傳輸”意思是“一次I/O請求”。多個邏輯請求可能會被合併為“一次I/O請求”。“一次傳輸”請求的大小是未知的。 kB_read/s:每秒從裝置(drive expressed)讀取的資料量;
kB_read:讀取的總資料量;
kB_wrtn/s:每秒向裝置(drive expressed)寫入的資料量;
kB_wrtn:寫入的總數量資料量;這些單位都為Kilobytes。
iostat -cdx 1 >outfile
cat outfile
vmstat: 也可以輸出到檔案vmstat > outputfile

Procs r: The number of processes waiting for run time. b: The number of processes in uninterruptable sleep. w: The number of processes swapped out but otherwise runnable.

Memory swpd: the amount of virtual memory used (kB). free: the amount of idle memory (kB). buff: the amount of memory used as buffers (kB).

Swap si: Amount of memory swapped in from disk (kB/s). so: Amount of memory swapped to disk (kB/s).

IO bi: Blocks sent to a block device (blocks/s). bo: Blocks received from a block device (blocks/s).

System in: The number of interrupts per second, including the clock. cs: The number of context switches per second.

CPU These are percentages of total CPU time. us: user time sy: system time id: idle time

檔案控制代碼數Too many open files

問題描述:java .io.IOException: Too many open files

[[email protected] ~]#ulimit -a(檢視檔案控制代碼數) core file size          (blocks, -c) 0 data seg size           (kbytes, -d) unlimited max nice                        (-e) 0 file size               (blocks, -f) unlimited pending signals                 (-i) 71680 max locked memory       (kbytes, -l) 32 max memory size         (kbytes, -m) unlimited open files                      (-n) 1024 pipe size            (512 bytes, -p) 8 POSIX message queues     (bytes, -q) 819200 max rt priority                 (-r) 0 stack size              (kbytes, -s) 10240 cpu time               (seconds, -t) unlimited max user processes              (-u) 71680 virtual memory          (kbytes, -v) unlimited file locks                      (-x) unlimited

[[email protected] ~]# ulimit -n 1024

ulimit應該是使用者的限制 ,如果太小則修改大小:ulimit -n 2048

如果要重啟後仍生效,則可修改/etc/security/limits.conf,後面加上: * - nofile 2048 (此時type用“-”,表示hard和soft同時設定。domain設定為星號代表全域性,也可以針對不同的使用者做出不同的限制 )

/proc/sys/fs/file-max應該是系統級的限制

[[email protected] ~]# cat /proc/sys/fs/file-max(檢視)

8192

[[email protected] ~]# echo 65536 > /proc/sys/fs/file-max(修改)

如果要重啟後仍生效,則可修改 /etc/sysctl.conf,加上:fs.file-max = 65536

另外還有一個,/proc/sys/fs/file-nr

只讀,可以看到整個系統目前使用的檔案控制代碼數量

相關推薦

Java線上應用故障排查之一CPU佔用【轉】

近期java應用,CPU使用率一直很高,經常達到100%,通過以下步驟完美解決,分享一下。 方法一: 轉載:http://www.linuxhot.com/java-cpu-used-high.html 1.jps 獲取Java程序的PID。 2.jstack pid

Java線上應用故障排查之一CPU佔用

一個應用佔用CPU很高,除了確實是計算密集型應用之外,通常原因都是出現了死迴圈。 以我們最近出現的一個實際故障為例,介紹怎麼定位和解決這類問題。 根據top命令,發現PID為28555的Java程序佔用CPU高達200%,出現故障。 通過ps aux | gre

線上應用故障排查之一CPU佔用

一個應用佔用CPU很高,除了確實是計算密集型應用之外,通常原因都是出現了死迴圈。 以我們最近出現的一個實際故障為例,介紹怎麼定位和解決這類問題。 根據top命令,發現PID為28555的Java程序佔用CPU高達200%,出現故障。 通過ps aux | grep PID命令,可以進一步確定是t

故障排查之一CPU佔用

http://www.blogjava.net/hankchen/archive/2012/05/09/377735.html 一個應用佔用CPU很高,除了確實是計算密集型應用之外,通常原因都是出現了死迴圈。 根據top命令,發現PID為28555的Java程序佔用CPU高達200%,出現故

壓測過程中故障排查之一CPU占用問題分析案例

一段 運行 應用 進行 返回 sco close 找到 java 說明: 一個應用占用CPU很高,除了確實是計算密集型應用之外,通常原因都是出現了死循環 以我們最近出現的一個實際故障為例,介紹怎麽定位和解決這類問題。 根據top命令,發現PID為28555的Java進程占

線上應用故障排查之二內存占用

int tool iter net 參數 top jmap命令 eap tom 前一篇介紹了線上應用故障排查之一:高CPU占用,這篇主要分析高內存占用故障的排查。 搞Java開發的,經常會碰到下面兩種異常: 1、java.lang.OutOfMemoryError: Per

Java線上應用故障排查之二記憶體佔用

搞Java開發的,經常會碰到下面兩種異常: 1、java.lang.OutOfMemoryError: PermGen space 2、java.lang.OutOfMemoryError: Java heap space 要詳細解釋這兩種異常,需要簡單重提下J

Java應用故障CPU佔用的問題及排查方案

做為應用負責人,誰都希望自己負責的應用能夠在線上跑得順順當當,不出任何錯誤,也不產生任何告警,當然這是最理想的結果,也是做為技術人員希望達到的最終效果。可是實事上應用就像小孩一樣,總會在不經意間,不按你期望的結果執行,如CPU偏高、記憶體佔用偏高、應用沒有響應、應用自動掛掉等

JAVA程序CPU佔用故障排查

問題描述:生產環境下的某臺tomcat7伺服器,在剛釋出時的時候一切都很正常,在執行一段時間後就出現CPU佔用很高的問題,基本上是負載一天比一天高。問題分析:1,程式屬於CPU密集型,和開發溝通過,排除此類情況。2,程式程式碼有問題,出現死迴圈,可能性極大。問題解決:1,開

生產環境下JAVA程序CPU佔用故障排查

轉自:http://blog.chinaunix.net/uid-10449864-id-3463151.html 問題描述: 生產環境下的某臺tomcat7伺服器,在剛釋出時的時候一切都很正常,在執行一段時間後就出現CPU佔用很高的問題,基本上是負載一天比一天高。 問題分

Node.js 應用故障排查手冊 —— 利用 CPU 分析調優吞吐量

開發十年,就只剩下這套架構體系了! >>>   

Node.js 應用故障排查手冊 —— Node.js 效能平臺使用指南

開發十年,就只剩下這套架構體系了! >>>   

Node.js 應用故障排查手冊 —— 正確開啟 Chrome devtools

開發十年,就只剩下這套架構體系了! >>>   

Node.js 應用故障排查手冊 —— 綜合性 GC 問題和優化

今年企業對Java開發的市場需求,你看懂了嗎? >>>   

Node.js 應用故障排查手冊 —— 雪崩型記憶體洩漏問題

楔子 實踐篇一中我們也看到了一個比較典型的由於開發者不當使用第三方庫,而且在配置資訊中攜帶了三方庫本身使用不到的資訊,導致了記

一個TomcatCPU佔用問題的定位

      前段時間專案(交接過來的)釋出了一個大的版本以後,IDC機器CPU不時會突然飆升,而且是“根本停不下來”的樣子,一上去了就是100%。想來也納悶,雖然發了版本,但沒有太耗CPU的功能,不應該會讓CPU一下子從20%左右飆升到100%

Linux中模擬診斷OracleCPU佔用

 下面是模擬過程 1,在一個session中模擬CPU高使用率,如下:declare num int:=0; begin loop num:=num+1; end loop; end; /2,在shell視窗用top命令檢視CPU使用情況:  PID USER PR

線上故障排查-記憶體佔用

這篇主要分析高記憶體佔用故障的排查。 搞Java開發的,經常會碰到下面兩種異常: 1、java.lang.OutOfMemoryError: PermGen space 2、java.lang.OutOfMemoryError: Java heap space 要詳細

Java程序故障排查CPU資源佔用,介面響應超時,功能介面停滯等)

故障分析 # 導致系統不可用情況(頻率較大):     1)程式碼中某個位置讀取資料量較大,導致系統記憶體耗盡,進而出現Full GC次數過多,系統緩慢;     2)程式碼中有比較消耗CPU的操作,導致CPU過高,系統執

mysql 線上故障排查

mysql 線上故障排查Mysql 系統報連接池滿iostatslowlogWhat’s in slow log?Mk-query-digest mk-query-digest 全面分析slow log本文出自 “李世龍” 博客,謝絕轉載!mysql 線上故障排查