如何排查解決線上問題-java版

-- 關鍵須要作好監控和報警,打日誌要準確規範。 博客地址html

性能類

診斷

uptime

查看當前load(cpu負載信息)java

top

按P 按照cpu排序 按M按內存排序 按T按cpu時間消耗排序linux

更多參考ios

<!-- more -->git

vmstat 1

procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----

r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st

0  0      0 151732 867452 3261568    0    0     0     5    0    0  1  1 98  0  0
  • 進程信息

r: 等待運行的進程數 b: 處於不能夠中斷的睡眠狀態的進程數github

  • 內存信息

swpd: 使用的虛擬內存總量 free: 空閒內存總量 buff: 用來當buffer的內存的總量(已經write的IO) cache: cache的內存,read的IO編程

  • swap

swap in swap out緩存

  • IO

bi 塊設備每秒接收的塊的數量 bo 塊設備每秒發送的塊的數量網絡

  • 系統

cs: context switch 上下文切換次數 us: 用戶cpu時間。 sy: 內核系統cpu時間。若是過高表示系統調用時間長 id: 空閒cpu時間 wa: 用來等待io花費的時間 st: time stolen from a virtoal machien.app

iostat 1

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           1.00    0.00    0.50    0.00    0.00   98.50

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
vda               0.00         0.00         0.00          0          0
vdb               0.00         0.00         0.00          0          0
vdc               2.00         0.00        16.00          0         16

dstat

----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw
  1   1  99   0   0   0| 236B   54k|   0     0 |   0     0 | 832  6976
  1   0  99   0   0   0|   0    16k|6674B 8590B|   0     0 |1788  3463
  1   0  99   0   0   0|   0    16k|6782B 7182B|   0     0 |1824  3443
  1   1  98   0   0   0|   0    16k|6882B 8121B|   0     0 |1724  3352

pidstat 1

sar -n DEV 1

統計網絡情況

16:45:37        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s  
16:45:38           lo      8.00      8.00      0.73      0.73      0.00      0.00      0.00  
16:45:38         eth0      1.00      1.00      0.06      0.11      0.00      0.00      0.00

rxpck: 每秒收到的包的數量
txpck: 傳輸的包的數量
rxkB: 收到的kB大小
txkB: 傳輸的kB大小
rxcmp: 壓縮的包的收到的數量
txcmp: 壓縮的包的傳輸量
rxmcst: 收到的廣播的包的數量

free -m

查看情況內存。

total       used       free     shared    buffers     cached
Mem:          7870       7188        681          0        273       4796
-/+ buffers/cache:       2119       5751
Swap:         2047          0       2047

Mem: 是系統角度的內存狀態
total 7870M, 使用了7188M, 681M可用,0M共享,273 buffer, 4796 cached.
-/+ buffers/cache: 是算和不算緩存緩衝的狀況
2119: 不算時已使用內存
5751: 不算時可用內存
Swap:swap使用狀況

http://www.cnblogs.com/coldplayerest/archive/2010/02/20/1669949.html
less /proc/meminfo

網絡

  • netstat -nltp
  • netstat -anpt
  • netstat -ntp | grep 'TIME_WAIT' | awk '{print $5, $6}' | awk -F ':' '{print $1, $2}' | awk '{print $1, $3}' | sort | uniq -c | sort -k 1 -n -r
  • netstat -nt | grep 11300 | awk '{print $5}' | awk -F ':' '{print $1}' | sort | uniq -c 查看某個端口號的鏈接的主機數量統計
  • lsof -i:8080
  • lsof -p pid

磁盤

  • df -h 查看磁盤總佔用狀況
  • du -h . --max-depth=0 查看當前文件夾下各個文件佔用大小,文件夾深度爲0

gc

  • jps -l
94422
9671 sun.tools.jps.Jps
96568 com.intellij.rt.execution.application.AppMain
  • jps -lv

  • jinfo -flags pid

jinfo -flags 96568
Attaching to process ID 96568, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.45-b02
Non-default VM flags: -XX:CICompilerCount=4 -XX:InitialHeapSize=268435456 -XX:MaxHeapSize=4294967296 -XX:MaxNewSize=1431306240 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=89128960 -XX:OldSize=179306496 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC
Command line:  -Drebel.base=/Users/liuzhengyang/.jrebel -Drebel.env.ide.plugin.version=6.5.0 -Drebel.env.ide.version=2016.2.2 -Drebel.env.ide.product=IU -Drebel.env.ide=intellij -Drebel.notification.url=http://localhost:17434 -javaagent:/var/folders/lg/wvtqlfn13lx5kfp0p_pf_hx00000gn/T/jrebel-temp/jrebel.jar -Dmaven.home=/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3 -Dclassworlds.conf=/Applications/IntelliJ IDEA.app/Contents/plugins/maven/lib/maven3/bin/m2.conf -Didea.launcher.port=7532 -Didea.launcher.bin.path=/Applications/IntelliJ IDEA.app/Contents/bin -Dfile.encoding=UTF-8
  • jstat -gcutil pid 1s
S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
  0.00   2.47  80.24  44.07  97.73  94.31     27    1.271     3    0.431    1.702
  0.00   2.47  80.24  44.07  97.73  94.31     27    1.271     3    0.431    1.702
  • jstat -gccause pid 1s

  • 查看gc.log

  • jstack -l

 
  • 查看某個進行內佔用cpu最多的進程 top -Hp pid 找到後,轉換成16進行 如printf '%x\n' pid
printf '%x\n' 8241

獲得2031 再在jstack 結果中查找這個線程號對應的線程是什麼

  • jstack -l 中查看是否有死鎖 #TODO

  • jmap -histo pid

  • jmap -histo:live pid

  • jmap -histo:live pid | less 查看對象實例數量佔用內存最多的幾個類,從中查找可能出現的問題

  • jmap -heap pid

  • dump 內存文件

jmap -dump:format=b,file=dump.bin,live 8176

dump下來後能夠用MAT來分析內存引用,觀察內存佔用狀況 ,那個地方致使了內存泄露等等。

tcp

  • ifconfig查看有哪些網卡和相應的參數,ip,mtu等
  • netstat 類 TODO
  • 有root權限時,能夠執行tcpdump 查看tcp 端口是8888的來源hostIP是10.0.0.1的請求
tcpdump -i eth0 tcp port 8888 and src host 10.0.0.1

更多參考

  • 查看TCP參數 less /etc/sysctl.conf

查看多臺機器的工具

代碼類

拋異常

編寫代碼時要在關鍵的位置

  • 調用外部服務、遠程方式時,要將參數、結果上打印log出來。日誌要注意發生異常時是否可以打印、是否能打出足夠信息。
  • 一些關鍵的步驟,打印參數等
  • 異常處理的地方,打印參數,異常棧 這樣就能夠在程序拋出異常的時候,經過異常棧以及咱們打印的參數快速的判斷是哪裏出現了問題。 經過異常棧分析那個位置的代碼出錯了,若是有參數就能分析出爲何出錯。經過查找Cause by能夠找到最初拋出異常的位置。

防護式編程

  • 不要對外來的參數作假設,不要假設外部參數不是null或者其中任意一個屬性不是null,都要進行判斷,能夠 經過Preconditions類或StringUtils.isNotEmptyCollectionUtils.isNotEmpty等進行 防護
  • 在循環處理的地方,若是但願其中一個循環出錯不影響其餘循環的執行時,要在循環內部catch
for (e in loop) {
    try {
        do loop
    } catch (Exception e) {
        log and exception handle
    }
}
  • 防護式拷貝 Defensive copy. 當一個方法返回一個對象時,咱們要考慮外部調用方可能會修改這個對象的值,致使其餘引用這個對象的地方 觀察到狀態改變。這種隱含的變化可能帶來bug。經過defensive copy,返回一個新的對象,避免了共享對象。可是要注意的是, copy也有深度copy和淺copy。另外一種方式是返回一個不可修改的集合,如Collections.unmodifiableCollection等。

啓動類

java啓動報錯

常常出現的狀況是,在本地開發沒有問題、或是在staging測試也沒問題,部署到線上啓動就報錯了。 這個時候仍是須要在編寫代碼時就提早注意,有哪些用到了依賴於環境的地方 如

  • 服務依賴,各個環境的服務配置、服務是否存在
  • 端口,是否和已有的程序的端口衝突了
  • 權限,寫文件或者日誌目錄是否有權限

另外還有maven引用jar包衝突的,會出現NoSuchMethodError等錯誤
這個時候,找到哪一個類的版本不一致,在代碼中找到對應的依賴的jar包
經過mvn dependency:tree | grep進行查看有哪些地方引入了jar包。
maven 採用的是按照聲明順序靠前的使用。

當能夠進行必定的調試時,只在staging環境或者有一個jsp頁面能夠調用java代碼時, 可使用Class.forName("xxx").getClassLoader XXX.class.getResource("xxx.yy.ZZZ") 來查看用的是那個地方的class文件 也能夠解壓jar包,使用javap -v -p -c 查看class文件內容 另外還有一些工具,像BTrace、housemd、greys來幫助咱們線上調試

相關文章
相關標籤/搜索