觀測目標與工具對應
| 維度 | 核心指標 | 首選工具 | 進階工具 |
| CPU | 使用率、負載、上下文切換、執行佇列 | top, htop, mpstat, pidstat | perf, bpftrace, turbostat |
| 記憶體 | 用量、快取、交換、頁面錯誤、OOM | free, vmstat, pidstat -r | smem, numa_maps, bpftrace |
| I/O | IOPS、吞吐、延遲、佇列深度、飽和度 | iostat, pidstat -d, iotop | blktrace, bcc biolatency, bpftrace |
| 網路 | 頻寬、連線數、重傳、延遲、封包率 | ss, netstat, nload, iftop, nethogs | tcpdump, bpftrace, bcc tcplife |
| Java/JVM | 堆/非堆、GC、執行緒、類別、JIT | jstat, jmap, jstack, jcmd | async-profiler, JFR, Arthas, Greys |
一、CPU 與執行緒熱點定位
1. 找出最耗 CPU 的 Java 執行緒
# 1. 取得 Java 進程 PID
PID=$(pgrep -f java)
# 2. 列出所有執行緒 CPU 佔用 (需 procps-ng 3.3.10+)
ps -Lfp $PID
# 或
ps -T -p $PID -o pid,tid,pcpu,time,cmd
# 3. 找出最高佔用 TID (十進位)
# 假設 TID=30834
# 4. 轉十六進位
printf "%x\n" 30834
# 輸出如 7872
# 5. 產生堆疊快照
jstack $PID > threaddump.txt
# 或生產環境安全
jcmd $PID Thread.print > threaddump.txt
# 6. 搜尋對應 nid (十六進位)
grep -A 20 "nid=0x7872" threaddump.txt
# 定位到具體程式碼行
2. top 互動式即時觀測
top -H -p $PID
# 按 P 排序 CPU,按 M 排序記憶體
# c 顯示完整命令列
# 1 切換 CPU 核心視圖
3. mpstat 多核心負載均衡
mpstat -P ALL 1 10
# 關注 %iowait (I/O 等待)、%soft (軟中斷)、%irq (硬中斷)、%steal (虛擬化偷取)
# 單核心 100% 且 %iowait 高 → I/O 瓶頸
# %soft/%irq 高 → 網路/磁碟中斷風暴
4. pidstat 單進程全維度
pidstat -p $PID -u -d -r -w -t -h 1 10
# -u CPU, -d I/O, -r 記憶體, -w context switch, -t 執行緒, -h 顯示表頭
# 輸出含每個執行緒獨立指標
5. sar 歷史資料 (需 sysstat 啟用)
sar -u 1 10 # CPU
sar -r 1 10 # 記憶體
sar -d 1 10 # 磁碟 (需 SADC_OPTIONS="-S DISK")
sar -n DEV 1 10 # 網路介面
sar -x $PID 1 10 # 指定進程
二、I/O 瓶頸精準判斷
iostat 關鍵指標解讀
iostat -xmt 1 10
# -x 延伸, -m MB/s, -t 時間戳
關鍵欄位:
r/s, w/s # 每秒讀/寫請求數 (IOPS)
rkB/s, wkB/s # 每秒讀/寫 KB (吞吐)
await # 平均 I/O 完成時間 (ms) = queue + service
svctm # 平均裝置服務時間 (ms)
%util # 裝置飽和度 (100% 表示飽和)
aqu-sz # 平均佇列長度 (現代核心), 取代 avgqu-sz
判斷邏輯:
%util 接近 100% + await 遠大於 svctm → 佇列堆積,I/O 瓶頸
await 高但 %util 低 → 單次 I/O 慢 (網路儲存/快照/重構)
aqu-sz 持續 > 設備佇列深度 → 佇列滿,需調整 I/O scheduler
blktrace / bcc / bpftrace 深度剖析
# blktrace 原始追蹤
blktrace -d /dev/sda -o - | blkparse -i -
# bcc biolatency 延遲分布
/usr/share/bcc/tools/biolatency 10
# bpftrace 一行指令
bpftrace -e 'kprobe:blk_account_io_done { @[comm] = hist(arg0); }'
三、網路觀測
連線狀態與埠口
ss -tanp | head -20 # TCP 連線 + 進程 (現代替代 netstat)
ss -s # 統計摘要
ss -tan state established # 已建立連線
ss -tan sport = :80 # 特定埠口
# 監控連線數變化
watch -n 1 'ss -tan state established | wc -l'
頻寬與流量
nload eth0 # 即時頻寬圖
iftop -i eth0 # 連線級流量 (需 root)
nethogs eth0 # 進程級流量 (需 root)
bmon -p eth0 # 詳細統計
封包分析
tcpdump -i eth0 -nn -s0 -w capture.pcap port 80
# -nn 不解析域名/埠口, -s0 完整封包
# bpftrace TCP 連線壽命
bpftrace -e 'kprobe:tcp_connect_init { @[comm] = count(); } interval:s:10 { print(@); }'
# bcc tcplife 連線延遲
/usr/share/bcc/tools/tcplife
四、Java/JVM 全棧觀測
標準工具鏈
| 工具 | 功能 | 關鍵參數 |
| jps | 列出 JVM 進程 | -lv 顯示主類別/參數 |
| jstat | GC/編譯/類別統計 | -gcutil -h10 $PID 1000 10 |
| jmap | 堆轉儲/統計 | -histo:live $PID, -dump:live,format=b,file=heap.hprof $PID |
| jstack | 執行緒堆疊 | -l $PID (含鎖資訊) |
| jcmd | 診斷命令集 | VM.flags, GC.class_histogram, Thread.print, JFR.start |
| jhsdb | Core dump 分析 | jhsdb jstack --exe java --core core.1234 |
現代診斷工具
- async-profiler:低開銷 CPU/分配/鎖分析火焰圖
./profiler.sh -d 60 -f profile.html $PID
- JFR (Java Flight Recorder):JDK 11+ 內建事件記錄
jcmd $PID JFR.start name=rec settings=profile duration=60s filename=rec.jfr
- Arthas:阿里開源線上診斷
java -jar arthas-boot.jar → dashboard, thread, trace, watch, tt
- Greys:另一線上診斷工具,類 Arthas
GC 分析核心指標
jstat -gcutil $PID 1000
S0 S1 E O M CCS YGC YGCT FGC FGCT GCT
0.00 98.00 45.00 60.00 85.00 90.00 120 2.500 5 1.200 3.700
關注:
- O (Old Gen) 使用率持續 > 85% → Full GC 頻繁
- FGCT (Full GC Time) 佔 GCT 比例高 → 停頓長
- YGC/YGCT 比例 → Young GC 效率
- Metaspace (M/CCS) 增長不止 → 類別洩漏
五、綜合儀表板與自動化
Netdata (單機即時)
bash <(curl -Ss https://my-netdata.io/kickstart.sh)
# 瀏覽 https://localhost:19999
Prometheus + Node Exporter + Grafana (叢集級)
# Node Exporter
docker run -d --net=host --pid=host -v /:/host:ro,rslave quay.io/prometheus/node-exporter --path.rootfs=/host
# Prometheus scrape config
- job_name: node
static_configs:
- targets: ['localhost:9100']
# Grafana Import Dashboard 1860 (Node Exporter Full)
bpftrace 系統級一行指令庫
# 開檔案追蹤
bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s(%d) open %s\n", comm, pid, str(args->filename)); }'
# 新進程
bpftrace -e 'tracepoint:sched:sched_process_exec { printf("%s[%d] exec %s\n", comm, pid, args->filename); }'
# TCP 重傳
bpftrace -e 'kprobe:tcp_retransmit_skb { @[comm] = count(); } interval:s:5 { print(@); }'
# 記憶體分配熱點
bpftrace -e 'kprobe:kmalloc { @[kstack] = count(); } interval:s:30 { print(@); }'
六、指令安裝備忘
# Ubuntu/Debian
apt update && apt install -y procps sysstat htop iotop iftop nethogs nload bmon tcpdump bpftrace linux-tools-common linux-tools-$(uname -r)
# RHEL/Fedora/CentOS
dnf install -y procps-ng sysstat htop iotop iftop nethogs nload bmon tcpdump bpftrace bcc perf
# Java 工具隨 JDK 提供 (jstat, jmap, jstack, jcmd, jfr, jhsdb)
# async-profiler: https://github.com/jvm-profiling-tools/async-profiler/releases
# Arthas: https://arthas.aliyun.com/doc/quick-start.html
核心心法:指標先行、分層定位、工具組合、自動化持續、知識沉澱。單一指標不足為憑,需 CPU/I/O/網路/應用四維交叉驗證。