作者 | xiaolyuh
free
free
是查看內存使用情況,包括物理內存、交換內存(swap)和內核緩衝區內存。
free -h -s 3
表示每隔三秒輸出一次內存情況,命令如下
[1014154@cc69dd4c5-4tdb5 ~]$ free
total used free shared buff/cache available
Mem: 119623656 43052220 45611364 4313760 30960072 70574408
Swap: 0 0 0
[1014154@cc69dd4c5-4tdb5 ~]$ free -h -s 3
total used free shared buff/cache available
Mem: 114G 41G 43G 4.1G 29G 67G
Swap: 0B 0B 0B
total used free shared buff/cache available
Mem: 114G 41G 43G 4.1G 29G 67G
Swap: 0B 0B 0B
-
Mem
:是內存的使用情況。 -
Swap
:是交換空間的使用情況。 -
total
:系統總的可用物理內存和交換空間大小。 -
used
:已經被使用的物理內存和交換空間。 -
free
:還有多少物理內存和交換空間可用使用,是真正尚未被使用的物理內存數量。 -
shared
:被共享使用的物理內存大小。 -
buff/cache
:被 buffer(緩衝區) 和 cache(緩存) 使用的物理內存大小。 -
available
:還可以被應用程序使用的物理內存大小,它是從應用程序的角度看到的可用內存數量,available ≈ free + buffer + cache。
交換空間(swap space)
swap space 是磁盤上的一塊區域,當系統物理內存喫緊時,Linux 會將內存中不常訪問的數據保存到 swap 上,這樣系統就有更多的物理內存爲各個進程服務,而當系統需要訪問 swap 上存儲的內容時,再將 swap 上的數據加載到內存中,這就是常說的換出和換入。交換空間可以在一定程度上緩解內存不足的情況,但是它需要讀寫磁盤數據,所以性能不是很高。
vmstat(推薦)
vmstat(VirtualMeomoryStatistics,虛擬內存統計)是Linux中監控內存的常用工具,可對操作系統的虛擬內存、進程、CPU等的整體情況進行監視,推薦使用。
vmstat 5 3
表示每隔5秒統計一次,一共統計三次。
[1014154@cc69dd4c5-4tdb5 ~]$ vmstat 5 3
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
8 0 0 45453212 374768 30763728 0 0 14 99 1 1 11 10 78 0 1
10 0 0 45489232 374768 30763360 0 0 2 1275 95118 97908 13 11 75 0 1
6 0 0 45452908 374768 30765148 0 0 0 3996 89924 92073 12 10 78 0 1
procs
r
:表示運行和等待CPU時間片的進程數(就是說多少個進程真的分配到CPU),這個值如果長期大於系統CPU個數,說明CPU不足,需要增加CPU。b
:表示在等待資源的進程數,比如正在等待I/O或者內存交換等。
memory
swpd
:表示切換到內存交換區的內存大小,即虛擬內存已使用的大小(單位KB),如果大於0,表示你的機器物理內存不足了,如果不是程序內存泄露的原因,那麼你該升級內存了或者把耗內存的任務遷移到其他機器。free
:表示當前空閒的物理內存。buff
:表示緩衝大小,一般對塊設備的讀寫才需要緩衝 Cache
:表示緩存大小,一般作爲文件系統進行緩衝,頻繁訪問的文件都會被緩存,如果cache值非常大說明緩存文件比較多,如果此時io中的bi比較小,說明文件系統效率比較好。
swap
si
:表示數據由磁盤讀入內存;通俗的講就是每秒從磁盤讀入虛擬內存的大小,如果這個值大於0,表示物理內存不夠用或者內存泄露了,要查找耗內存進程解決掉。so
:表示由內存寫入磁盤,也就是由內存交換區進入內存的數據大小。
!! 注意:一般情況下si、so的值都爲0,如果si、so的值長期不爲0,則說明系統內存不足,需要增加系統內存
io
bi
:表示由塊設備讀入數據的總量,即讀磁盤,單位kb/s bo
:表示寫到塊設備數據的總量,即寫磁盤,單位kb/s
!! 注意:如果bi+bo的值過大,且wa值較大,則表示系統磁盤IO瓶頸。
system
in
:表示某一時間間隔內觀測到的每秒設備終端數。cs
:表示每秒產生的上下文切換次數,這個值要越小越好,太大了,要考慮調低線程或者進程的數目。例如在apache和nginx這種web服務器中,我們一般做性能測試時會進行幾千併發甚至幾萬併發的測試,選擇web服務器的進程可以由進程或者線程的峯值一直下調,壓測,直到cs到一個比較小的值,這個進程和線程數就是比較合適的值了。系統調用也是,每次調用系統函數,我們的代碼就會進入內核空間,導致上下文切換,這個是很耗資源,也要儘量避免頻繁調用系統函數。上下文切換次數過多表示你的CPU大部分浪費在上下文切換,導致CPU幹正經事的時間少了,CPU沒有充分利用,是不可取的。
!! 注意:這兩個值越大,則由內核消耗的CPU就越多。
CPU
us
:表示用戶進程消耗的CPU時間百分比,us值越高,說明用戶進程消耗CPU時間越多,如果長期大於50%,則需要考慮優化程序或者算法。sy
:表示系統內核進程消耗的CPU時間百分比,一般來說us+sy應該小於80%,如果大於80%,說明可能存在CPU瓶頸。id
:表示CPU處在空間狀態的時間百分比。wa
:表示IP等待所佔用的CPU時間百分比,wa值越高,說明I/O等待越嚴重,根據經驗wa的參考值爲20%,如果超過20%,說明I/O等待嚴重,引起I/O等待的原因可能是磁盤大量隨機讀寫造成的,也可能是磁盤或者監控器的貸款瓶頸(主要是塊操作)造成的。
sar
sar和free類似sar -r 3
每隔三秒輸出一次內存信息:
[root@localhost ~]# sar -r 3
Linux 3.10.0-1062.el7.x86_64 (localhost.localdomain) 2020年04月28日 _x86_64_ (2 CPU)
15時40分10秒 kbmemfree kbmemused %memused kbbuffers kbcached kbcommit %commit kbactive kbinact kbdirty
15時40分13秒 106800 1314960 92.49 2144 573248 4110864 116.82 563664 498888 36
15時40分16秒 106816 1314944 92.49 2144 573248 4110864 116.82 563668 498888 36
15時40分19秒 106816 1314944 92.49 2144 573248 4110864 116.82 563668 498888 36
CPU瓶頸
查看機器cpu核數
CPU總核數 = 物理CPU個數 * 每顆物理CPU的核數
總邏輯CPU數 = 物理CPU個數 * 每顆物理CPU的核數 * 超線程數
查看CPU信息(型號)
[1014154@cc69dd4c5-4tdb5 ~]$ cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c
32 Intel(R) Xeon(R) CPU E5-2650 v4 @ 2.20GHz
查看物理CPU個數
[1014154@cc69dd4c5-4tdb5 ~]$ cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l
16
查看每個物理CPU中core的個數(即核數)
[1014154@cc69dd4c5-4tdb5 ~]$ cat /proc/cpuinfo| grep "cpu cores"| uniq
cpu cores : 2
查看邏輯CPU的個數
[1014154@cc69dd4c5-4tdb5 ~]$ cat /proc/cpuinfo| grep "processor"| wc -l
32
top
在Linux內核的操作系統中,進程是根據虛擬運行時間(由進程優先級、nice值加上實際佔用的CPU時間進行動態計算得出)進行動態調度的。在執行進程時,需要從用戶態轉換到內核態,用戶空間不能直接操作內核空間的函數。通常要利用系統調用來完成進程調度,而用戶空間到內核空間的轉換通常是通過軟中斷來完成的。例如要進行磁盤操作,用戶態需要通過系統調用內核的磁盤操作指令,所以CPU消耗的時間被切分成用戶態CPU消耗、系統(內核) CPU 消耗,以及磁盤操作 CPU 消耗。執行進程時,需要經過一系列的操作,進程首先在用戶態執行,在執行過程中會進行進程優先級的調整(nice),通過系統調用到內核,再通過內核調用,硬中斷、軟中斷,讓硬件執行任務。執行完成之後,再從內核態返回給系統調用,最後系統調用將結果返回給用戶態的進程。
top可以查看CPU總體消耗,包括分項消耗,如User,System,Idle,nice等。Shift + H
顯示java線程;Shift + M
按照內存使用排序;Shift + P
按照CPU使用時間(使用率)排序;Shift + T
按照CPU累積使用時間排序;多核CPU,進入top視圖1
,可以看到各各CPU的負載情況。
top - 15:24:11 up 8 days, 7:52, 1 user, load average: 5.73, 6.85, 7.33
Tasks: 17 total, 1 running, 16 sleeping, 0 stopped, 0 zombie
%Cpu(s): 13.9 us, 9.2 sy, 0.0 ni, 76.1 id, 0.1 wa, 0.0 hi, 0.1 si, 0.7 st
KiB Mem : 11962365+total, 50086832 free, 38312808 used, 31224016 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 75402760 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
300 ymmapp 20 0 17.242g 1.234g 14732 S 2.3 1.1 9:40.38 java
1 root 20 0 15376 1988 1392 S 0.0 0.0 0:00.06 sh
11 root 20 0 120660 11416 1132 S 0.0 0.0 0:04.94 python
54 root 20 0 85328 2240 1652 S 0.0 0.0 0:00.00 su
55 ymmapp 20 0 17432 1808 1232 S 0.0 0.0 0:00.00 bash
56 ymmapp 20 0 17556 2156 1460 S 0.0 0.0 0:00.03 control.sh
57 ymmapp 20 0 11880 740 576 S 0.0 0.0 0:00.00 tee
115 ymmapp 20 0 17556 2112 1464 S 0.0 0.0 0:00.02 control_new_war
133 root 20 0 106032 4240 3160 S 0.0 0.0 0:00.03 sshd
134 ymmapp 20 0 17080 6872 3180 S 0.0 0.0 0:01.82 ops-updater
147 ymmapp 20 0 17956 2636 1544 S 0.0 0.0 0:00.07 control.sh
6538 ymmapp 20 0 115656 10532 3408 S 0.0 0.0 0:00.46 beidou-agent
6785 ymmapp 20 0 2572996 22512 2788 S 0.0 0.0 0:03.44 gatherinfo4dock
29241 root 20 0 142148 5712 4340 S 0.0 0.0 0:00.04 sshd
29243 1014154 20 0 142148 2296 924 S 0.0 0.0 0:00.00 sshd
29244 1014154 20 0 15208 2020 1640 S 0.0 0.0 0:00.00 bash
32641 1014154 20 0 57364 2020 1480 R 0.0 0.0 0:00.00 top
第一行:15:24:11 up 8 days, 7:52, 1 user, load average: 5.73, 6.85, 7.33
:15:24:11 系統時間,up 8 days 運行時間,1 user 當前登錄用戶數,load average 負載均衡情況,分別表示1分鐘,5分鐘,15分鐘負載情況。
第二行:Tasks: 17 total, 1 running, 16 sleeping, 0 stopped, 0 zombie
:總進程數17,運行數1,休眠 16,停止0,殭屍進程0。
第三行:%Cpu(s): 13.9 us, 9.2 sy, 0.0 ni, 76.1 id, 0.1 wa, 0.0 hi, 0.1 si, 0.7 st
:用戶空間CPU佔比13.9%,內核空間CPU佔比9.2%,改變過優先級的進程CPU佔比0%,空閒CPU佔比76.1,IO等待佔用CPU佔比0.1%,硬中斷佔用CPU佔比0%,軟中斷佔用CPU佔比0.1%,當前VM中的cpu 時鐘被虛擬化偷走的比例0.7%。
第四和第五行表示內存和swap區域的使用情況。
第七行表示:
-
PID
: 進程id -
USER
:進程所有者 -
PR
:進程優先級 -
NI
:nice值。負值表示高優先級,正值表示低優先級 -
VIRT
:虛擬內存,進程使用的虛擬內存總量,單位kb。VIRT=SWAP+RES -
RES
:常駐內存,進程使用的、未被換出的物理內存大小,單位kb。RES=CODE+DATA -
SHR
:共享內存,共享內存大小,單位kb -
S
:進程狀態。D=不可中斷的睡眠狀態 R=運行 S=睡眠 T=跟蹤/停止 Z=殭屍進程 -
%CPU
:上次更新到現在的CPU時間佔用百分比 -
%MEM
:進程使用的物理內存百分比 -
TIME+
:進程使用的CPU時間總計,單位1/100秒 -
COMMAND
:進程名稱(命令名/命令行)
計算在cpu load裏面的uninterruptedsleep的任務數量
top -b -n 1 | awk '{if (NR<=7)print;else if($8=="D"){print;count++}}END{print "Total status D:"count}'
[root@localhost ~]# top -b -n 1 | awk '{if (NR<=7)print;else if($8=="D"){print;count++}}END{print "Total status D:"count}'
top - 15:35:05 up 1 day, 26 min, 3 users, load average: 0.00, 0.01, 0.05
Tasks: 225 total, 1 running, 224 sleeping, 0 stopped, 0 zombie
%Cpu(s): 2.5 us, 10.0 sy, 0.0 ni, 87.5 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1421760 total, 104516 free, 777344 used, 539900 buff/cache
KiB Swap: 2097148 total, 2071152 free, 25996 used. 456028 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
Total status D:
sar
通過sar -u 3
可以查看CUP總體消耗佔比:
[root@localhost ~]# sar -u 3
Linux 3.10.0-1062.el7.x86_64 (localhost.localdomain) 2020年05月01日 _x86_64_ (2 CPU)
15時18分03秒 CPU %user %nice %system %iowait %steal %idle
15時18分06秒 all 0.00 0.00 0.17 0.00 0.00 99.83
15時18分09秒 all 0.00 0.00 0.17 0.00 0.00 99.83
15時18分12秒 all 0.17 0.00 0.17 0.00 0.00 99.66
15時18分15秒 all 0.00 0.00 0.00 0.00 0.00 100.00
15時18分18秒 all 0.00 0.00 0.00 0.00 0.00 100.00
-
%user
:用戶空間的CPU使用。 -
%nice
:改變過優先級的進程的CPU使用率。 -
%system
:內核空間的CPU使用率。 -
%iowait
:CPU等待IO的百分比 。 -
%steal
:虛擬機的虛擬機CPU使用的CPU。 -
%idle
:空閒的CPU。
在以上的顯示當中,主要看%iowait
和%idle
:
-
若 %iowait
的值過高,表示硬盤存在I/O瓶頸; -
若 %idle
的值高但系統響應慢時,有可能是 CPU 等待分配內存,此時應加大內存容量; -
若 %idle
的值持續低於 10,則系統的 CPU 處理能力相對較低,表明系統中最需要解決的資源是 CPU;
定位線上最耗CPU的線程
準備工作
啓動一個程序。arthas-demo
是一個簡單的程序,每隔一秒生成一個隨機數,再執行質因數分解,並打印出分解結果。
curl -O https://alibaba.github.io/arthas/arthas-demo.jar
java -jar arthas-demo.jar
[root@localhost ~]# curl -O https://alibaba.github.io/arthas/arthas-demo.jar
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 3743 100 3743 0 0 3022 0 0:00:01 0:00:01 --:--:-- 3023
[root@localhost ~]# java -jar arthas-demo.jar
1813=7*7*37
illegalArgumentCount: 1, number is: -180005, need >= 2
illegalArgumentCount: 2, number is: -111175, need >= 2
18505=5*3701
166691=7*23813
105787=11*59*163
60148=2*2*11*1367
196983=3*3*43*509
illegalArgumentCount: 3, number is: -173479, need >= 2
illegalArgumentCount: 4, number is: -112840, need >= 2
39502=2*19751
....
通過top
命令找到最耗時的進程
[root@localhost ~]# top
top - 11:11:05 up 20:02, 3 users, load average: 0.09, 0.07, 0.05
Tasks: 225 total, 1 running, 224 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.7 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1421760 total, 135868 free, 758508 used, 527384 buff/cache
KiB Swap: 2097148 total, 2070640 free, 26508 used. 475852 avail Mem
Change delay from 3.0 to
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
98344 root 20 0 2422552 23508 12108 S 0.7 1.7 0:00.32 java
1 root 20 0 194100 6244 3184 S 0.0 0.4 0:20.41 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.12 kthreadd
4 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
6 root 20 0 0 0 0 S 0.0 0.0 0:20.25 ksoftirqd/0
找到進程號是98344。
找到進程中最耗CUP的線程
使用ps -Lp #pid cu
命令,查看某個進程中的線程CPU消耗排序:
[root@localhost ~]# ps -Lp 98344 cu
USER PID LWP %CPU NLWP %MEM VSZ RSS TTY STAT START TIME COMMAND
root 98344 98344 0.0 10 4.1 2422552 59060 pts/0 Sl+ 11:09 0:00 java
root 98344 98345 0.0 10 4.1 2422552 59060 pts/0 Sl+ 11:09 0:04 java
root 98344 98346 0.0 10 4.1 2422552 59060 pts/0 Sl+ 11:09 0:01 VM Thread
root 98344 98347 0.0 10 4.1 2422552 59060 pts/0 Sl+ 11:09 0:00 Reference Handl
root 98344 98348 0.0 10 4.1 2422552 59060 pts/0 Sl+ 11:09 0:00 Finalizer
root 98344 98349 0.0 10 4.1 2422552 59060 pts/0 Sl+ 11:09 0:00 Signal Dispatch
root 98344 98350 0.0 10 4.1 2422552 59060 pts/0 Sl+ 11:09 0:05 C2 CompilerThre
root 98344 98351 0.0 10 4.1 2422552 59060 pts/0 Sl+ 11:09 0:00 C1 CompilerThre
root 98344 98352 0.0 10 4.1 2422552 59060 pts/0 Sl+ 11:09 0:00 Service Thread
root 98344 98353 0.1 10 4.1 2422552 59060 pts/0 Sl+ 11:09 0:19 VM Periodic Tas
看TIME
列可以看出那個線程耗費CUP多,根據LWP
列可以看到線程的ID號,但是需要轉換成16進制纔可以查詢線程堆棧信息。
獲取線程id的十六進制碼
使用printf '%x\n' 98345
命令做進制轉換:
[root@localhost ~]# printf '%x\n' 98345
18029
查看線程堆棧信息
使用jstack獲取堆棧信息jstack 98344 | grep -A 10 18029
:
[root@localhost ~]# jstack 98344 | grep -A 10 18029
"main" #1 prio=5 os_prio=0 tid=0x00007fb88404b800 nid=0x18029 waiting on condition [0x00007fb88caab000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at demo.MathGame.main(MathGame.java:17)
"VM Thread" os_prio=0 tid=0x00007fb8840f2800 nid=0x1802a runnable
"VM Periodic Task Thread" os_prio=0 tid=0x00007fb884154000 nid=0x18031 waiting on condition
通過命令我們可以看到這個線程的對應的耗時代碼是在demo.MathGame.main(MathGame.java:17)
grep -C 5 foo file 顯示file文件裏匹配foo字串那行以及上下5行
grep -B 5 foo file 顯示foo及前5行
grep -A 5 foo file 顯示foo及後5行
網絡瓶頸
定位丟包,錯包情況
watch more /proc/net/dev
用於定位丟包,錯包情況,以便看網絡瓶頸,重點關注drop(包被丟棄)和網絡包傳送的總量,不要超過網絡上限:
[root@localhost ~]# watch -n 2 more /proc/net/dev
Every 2.0s: more /proc/net/dev Fri May 1 17:16:55 2020
Inter-| Receive | Transmit
face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
lo: 10025 130 0 0 0 0 0 0 10025 130 0 0 0 0 0 0
ens33: 759098071 569661 0 0 0 0 0 0 19335572 225551 0 0 0 0 0 0
-
最左邊的表示接口的名字,Receive表示收包,Transmit表示發送包; -
bytes
:表示收發的字節數; -
packets
:表示收發正確的包量; -
errs
:表示收發錯誤的包量; -
drop
:表示收發丟棄的包量;
查看路由經過的地址
traceroute ip
可以查看路由經過的地址,常用來統計網絡在各個路由區段的耗時,如:
[root@localhost ~]# traceroute 14.215.177.38
traceroute to 14.215.177.38 (14.215.177.38), 30 hops max, 60 byte packets
1 CD-HZTK5H2.mshome.net (192.168.137.1) 0.126 ms * *
2 * * *
3 10.250.112.3 (10.250.112.3) 12.587 ms 12.408 ms 12.317 ms
4 172.16.227.230 (172.16.227.230) 2.152 ms 2.040 ms 1.956 ms
5 172.16.227.202 (172.16.227.202) 11.884 ms 11.746 ms 12.692 ms
6 172.16.227.65 (172.16.227.65) 2.665 ms 3.143 ms 2.923 ms
7 171.223.206.217 (171.223.206.217) 2.834 ms 2.752 ms 2.654 ms
8 182.150.18.205 (182.150.18.205) 5.145 ms 5.815 ms 5.542 ms
9 110.188.6.33 (110.188.6.33) 3.514 ms 171.208.199.185 (171.208.199.185) 3.431 ms 171.208.199.181 (171.208.199.181) 10.768 ms
10 202.97.29.17 (202.97.29.17) 29.574 ms 202.97.30.146 (202.97.30.146) 32.619 ms *
11 113.96.5.126 (113.96.5.126) 36.062 ms 113.96.5.70 (113.96.5.70) 35.940 ms 113.96.4.42 (113.96.4.42) 45.859 ms
12 90.96.135.219.broad.fs.gd.dynamic.163data.com.cn (219.135.96.90) 35.680 ms 35.468 ms 35.304 ms
13 14.215.32.102 (14.215.32.102) 35.135 ms 14.215.32.110 (14.215.32.110) 35.613 ms 14.29.117.242 (14.29.117.242) 54.712 ms
14 * 14.215.32.134 (14.215.32.134) 49.518 ms 14.215.32.122 (14.215.32.122) 47.652 ms
15 * * *
...
查看網絡錯誤
netstat -i
可以查看網絡錯誤:
[root@localhost ~]# netstat -i
Kernel Interface table
Iface MTU RX-OK RX-ERR RX-DRP RX-OVR TX-OK TX-ERR TX-DRP TX-OVR Flg
ens33 1500 570291 0 0 0 225897 0 0 0 BMRU
lo 65536 130 0 0 0 130 0 0 0 LRU
-
Iface
: 網絡接口名稱; -
MTU
: 最大傳輸單元,它限制了數據幀的最大長度,不同的網絡類型都有一個上限值,如:以太網的MTU是1500; -
RX-OK
:接收時,正確的數據包數。 -
RX-ERR
:接收時,產生錯誤的數據包數。 -
RX-DRP
:接收時,丟棄的數據包數。 -
RX-OVR
:接收時,由於過速(在數據傳輸中,由於接收設備不能接收按照發送速率傳送來的數據而使數據丟失)而丟失的數據包數。 -
TX-OK
:發送時,正確的數據包數。 -
TX-ERR
:發送時,產生錯誤的數據包數。 -
TX-DRP
:發送時,丟棄的數據包數。 -
TX-OVR
:發送時,由於過速而丟失的數據包數。 -
Flg
:標誌,B 已經設置了一個廣播地址。L 該接口是一個回送設備。M 接收所有數據包(混亂模式)。N 避免跟蹤。O 在該接口上,禁用ARP。P 這是一個點到點鏈接。R 接口正在運行。U 接口處於“活動”狀態。
包的重傳率
cat /proc/net/snmp
用來查看和分析240秒內網絡包量,流量,錯包,丟包。通過RetransSegs
和OutSegs
來計算重傳率tcpetr=RetransSegs/OutSegs
。
[root@localhost ~]# cat /proc/net/snmp
Ip: Forwarding DefaultTTL InReceives InHdrErrors InAddrErrors ForwDatagrams InUnknownProtos InDiscards InDelivers OutRequests OutDiscards OutNoRoutes ReasmTimeout ReasmReqds ReasmOKs ReasmFails FragOKs FragFails FragCreates
Ip: 1 64 241708 0 0 0 0 0 238724 225517 15 0 0 0 0 0 0 0 0
Icmp: InMsgs InErrors InCsumErrors InDestUnreachs InTimeExcds InParmProbs InSrcQuenchs InRedirects InEchos InEchoReps InTimestamps InTimestampReps InAddrMasks InAddrMaskReps OutMsgs OutErrors OutDestUnreachs OutTimeExcds OutParmProbs OutSrcQuenchs OutRedirects OutEchos OutEchoReps OutTimestamps OutTimestampReps OutAddrMasks OutAddrMaskReps
Icmp: 149 0 0 50 99 0 0 0 0 0 0 0 0 0 147 0 147 0 0 0 0 0 0 0 0 0 0
IcmpMsg: InType3 InType11 OutType3
IcmpMsg: 50 99 147
Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts InCsumErrors
Tcp: 1 200 120000 -1 376 6 0 0 4 236711 223186 292 0 4 0
Udp: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors
Udp: 1405 438 0 1896 0 0 0
UdpLite: InDatagrams NoPorts InErrors OutDatagrams RcvbufErrors SndbufErrors InCsumErrors
UdpLite: 0 0 0 0 0 0 0
重傳率=292/223186≈0.13%
-
平均每秒新增TCP連接數:通過/proc/net/snmp文件得到最近240秒內PassiveOpens的增量,除以240得到每秒的平均增量; -
機器的TCP連接數 :通過/proc/net/snmp文件的CurrEstab得到TCP連接數; -
平均每秒的UDP接收數據報:通過/proc/net/snmp文件得到最近240秒內InDatagrams的增量,除以240得到平均每秒的UDP接收數據報; -
平均每秒的UDP發送數據報:通過/proc/net/snmp文件得到最近240秒內OutDatagrams的增量,除以240得到平均每秒的UDP發送數據報;
磁盤瓶頸
查磁盤空間
查看磁盤剩餘空間
查看磁盤剩餘空間使用df -hl
命令:
[root@localhost ~]# df -hl
文件系統 容量 已用 可用 已用% 掛載點
devtmpfs 678M 0 678M 0% /dev
tmpfs 695M 0 695M 0% /dev/shm
tmpfs 695M 28M 667M 4% /run
tmpfs 695M 0 695M 0% /sys/fs/cgroup
/dev/mapper/centos_aubin-root 27G 5.6G 22G 21% /
/dev/sda1 1014M 211M 804M 21% /boot
查看磁盤已使用空間
du -sh
命令是查看磁盤已使用空間的情況,這裏的“已使用的磁盤空間”意思是指定的文件下的整個文件層次結構所使用的空間,在沒給定參數的情況下,du
報告當前目錄所使用的磁盤空間。其實就是顯示文件或目錄所佔用的磁盤空間的情況:
[root@localhost ~]# du -sh
64K
-
-h
:輸出文件系統分區使用的情況,例如:10KB,10MB,10GB等。 -
-s
:顯示文件或整個目錄的大小,默認單位是KB。
!!
du
的詳細信息可以通過man du
查看。
查看磁盤讀寫情況
查看磁盤總體讀寫情況
通iostat
查看磁盤總體的讀寫情況:
[root@localhost ~]# iostat
Linux 3.10.0-1062.el7.x86_64 (localhost.localdomain) 2020年05月02日 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.17 0.00 0.20 0.46 0.00 99.17
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 1.56 30.45 39.61 4659620 6060644
scd0 0.00 0.02 0.00 3102 0
dm-0 1.96 30.01 38.42 4591998 5878155
dm-1 0.09 0.09 0.30 13840 45328
-
tps
:該設備每秒的傳輸次數。 -
kB_read/s
:每秒從設備(drive expressed)讀取的數據量; -
kB_wrtn/s
:每秒向設備(drive expressed)寫入的數據量; -
kB_read
:讀取的總數據量; -
kB_wrtn
:寫入的總數量數據量;
查看磁盤詳細讀寫情況
通過iostat -x 1 3
可以看到磁盤詳細讀寫情況,沒隔一秒輸出一次一共輸出3次,當看到I/O等待時間所佔CPU時間的比重很高的時候,首先要檢查的就是機器是否正在大量使用交換空間,同時關注iowait
佔比cpu的消耗是否很大,如果大說明磁盤存在大的瓶頸,同時關注await
,表示磁盤的響應時間以便小於5ms:
[root@localhost ~]# iostat -x 1 3
Linux 3.10.0-1062.el7.x86_64 (localhost.localdomain) 2020年05月02日 _x86_64_ (2 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.17 0.00 0.20 0.46 0.00 99.16
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.01 0.49 0.63 0.95 30.59 39.78 89.58 0.34 214.23 49.16 323.48 8.55 1.34
scd0 0.00 0.00 0.00 0.00 0.02 0.00 98.48 0.00 1.21 1.21 0.00 0.95 0.00
dm-0 0.00 0.00 0.62 1.35 30.15 38.59 69.70 0.91 460.67 49.12 648.54 6.66 1.31
dm-1 0.00 0.00 0.02 0.07 0.09 0.30 8.52 0.04 442.74 95.43 521.17 6.91 0.06
avg-cpu
表示總體cpu使用情況統計信息,對於多核cpu,這裏爲所有cpu的平均值:
-
%user
:CPU處在用戶模式下的時間百分比。 -
%nice
:CPU處在帶NICE值的用戶模式下的時間百分比。 -
%system
:CPU處在系統模式下的時間百分比。 -
%iowait
:CPU等待輸入輸出完成時間的百分比,如果%iowait的值過高,表示硬盤存在I/O瓶頸。 -
%steal
:管理程序維護另一個虛擬處理器時,虛擬CPU的無意識等待時間百分比。 -
%idle
:CPU空閒時間百分比,如果%idle值高,表示CPU較空閒;如果%idle值高但系統響應慢時,可能是CPU等待分配內存,應加大內存容量;如果%idle值持續低於10,表明CPU處理能力相對較低,系統中最需要解決的資源是CPU。。
Device
表示設備信息:
-
rrqm/s
:每秒對該設備的讀請求被合併次數,文件系統會對讀取同塊(block)的請求進行合併 -
wrqm/s
:每秒對該設備的寫請求被合併次數 -
r/s
:每秒完成的讀次數 -
w/s
:每秒完成的寫次數 -
rkB/s
:每秒讀數據量(kB爲單位) -
wkB/s
:每秒寫數據量(kB爲單位) -
avgrq-sz
:平均每次IO操作的數據量(扇區數爲單位) -
avgqu-sz
:平均等待處理的IO請求隊列長度 -
await
:平均每次IO請求等待時間(包括等待時間和處理時間,毫秒爲單位) -
svctm
:平均每次IO請求的處理時間(毫秒爲單位) -
%util
:一秒中有百分之多少的時間用於 I/O如果%util接近100%,說明產生的I/O請求太多,I/O系統已經滿負荷。idle
小於70% IO壓力就較大了,一般讀取速度有較多的wait。
!!
iostat -xmd 1 3
:新增m
選項可以在輸出是使用M
爲單位。
查看最耗IO的進程
一般先通過iostat
查看是否存在io瓶頸,再使用iotop
命令來定位那個進程最耗費IO:
[root@localhost ~]# iotop
Total DISK READ : 0.00 B/s | Total DISK WRITE : 0.00 B/s
Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 0.00 B/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
123931 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.02 % [kworker/1:30]
94208 be/4 xiaolyuh 0.00 B/s 0.00 B/s 0.00 % 0.00 % nautilus-desktop --force [gmain]
1 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % systemd --system --deserialize 62
2 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kthreadd]
94211 be/4 xiaolyuh 0.00 B/s 0.00 B/s 0.00 % 0.00 % gvfsd-trash --spawner :1.4 /org/gtk/gvfs/exec_spaw/0
4 be/0 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [kworker/0:0H]
6 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [ksoftirqd/0]
7 rt/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [migration/0]
8 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [rcu_bh]
9 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [rcu_sched]
10 be/0 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % [lru-add-drain]
...
通過iotop -p pid
可以查看單個進程的IO情況:
[root@localhost ~]# iotop -p 124146
Total DISK READ : 0.00 B/s | Total DISK WRITE : 0.00 B/s
Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 0.00 B/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
124146 be/4 root 0.00 B/s 0.00 B/s 0.00 % 0.00 % java -jar arthas-demo.jar
應用瓶頸
查看某個進程的PID
如查看java的進程的pid,ps -ef | grep java
:
[root@localhost ~]# ps -ef | grep java
root 124146 1984 0 09:13 pts/0 00:00:06 java -jar arthas-demo.jar
root 125210 98378 0 10:07 pts/1 00:00:00 grep --color=auto java
查看特定進程的數量
如查看java進程的數量,ps -ef | grep java| wc -l
:
[root@localhost ~]# ps -ef | grep java| wc -l
2
查看線程是否存在死鎖
查看線程是否存在死鎖,jstack -l pid
:
[root@localhost ~]# jstack -l 124146
2020-05-02 10:13:38
Full thread dump OpenJDK 64-Bit Server VM (25.252-b09 mixed mode):
"C1 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f27f013c000 nid=0x1e4f9 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f27f012d000 nid=0x1e4f8 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"main" #1 prio=5 os_prio=0 tid=0x00007f27f004b800 nid=0x1e4f3 waiting on condition [0x00007f27f7274000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at java.lang.Thread.sleep(Thread.java:340)
at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
at demo.MathGame.main(MathGame.java:17)
Locked ownable synchronizers:
- None
...
查看某個進程的線程數
ps -efL | grep [PID] | wc -l
,如:
[root@localhost ~]# ps -efL | grep 124146 | wc -l
12
查看具體有哪些線程用ps -Lp [pid] cu
:
[root@localhost ~]# ps -Lp 124146 cu
USER PID LWP %CPU NLWP %MEM VSZ RSS TTY STAT START TIME COMMAND
root 124146 124146 0.0 11 2.5 2489116 35724 pts/0 Sl+ 09:13 0:00 java
root 124146 124147 0.0 11 2.5 2489116 35724 pts/0 Sl+ 09:13 0:01 java
root 124146 124148 0.0 11 2.5 2489116 35724 pts/0 Sl+ 09:13 0:00 VM Thread
root 124146 124149 0.0 11 2.5 2489116 35724 pts/0 Sl+ 09:13 0:00 Reference Handl
root 124146 124150 0.0 11 2.5 2489116 35724 pts/0 Sl+ 09:13 0:00 Finalizer
root 124146 124151 0.0 11 2.5 2489116 35724 pts/0 Sl+ 09:13 0:00 Signal Dispatch
root 124146 124152 0.0 11 2.5 2489116 35724 pts/0 Sl+ 09:13 0:00 C2 CompilerThre
root 124146 124153 0.0 11 2.5 2489116 35724 pts/0 Sl+ 09:13 0:00 C1 CompilerThre
root 124146 124154 0.0 11 2.5 2489116 35724 pts/0 Sl+ 09:13 0:00 Service Thread
root 124146 124155 0.1 11 2.5 2489116 35724 pts/0 Sl+ 09:13 0:05 VM Periodic Tas
root 124146 125362 0.0 11 2.5 2489116 35724 pts/0 Sl+ 10:13 0:00 Attach Listener
統計所有的log文件中,包含Error字符的行
find / -type f -name "*.log" | xargs grep "ERROR"
,這個在排查問題過程中比較有用:
[root@localhost ~]# find / -type f -name "*.log" | xargs grep "ERROR"
/var/log/tuned/tuned.log:2020-03-13 18:05:59,145 ERROR tuned.utils.commands: Writing to file '/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor' error: '[Errno 19] No such device'
/var/log/tuned/tuned.log:2020-03-13 18:05:59,145 ERROR tuned.utils.commands: Writing to file '/sys/devices/system/cpu/cpu1/cpufreq/scaling_governor' error: '[Errno 19] No such device'
/var/log/tuned/tuned.log:2020-04-28 14:55:34,857 ERROR tuned.utils.commands: Writing to file '/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor' error: '[Errno 19] No such device'
/var/log/tuned/tuned.log:2020-04-28 14:55:34,859 ERROR tuned.utils.commands: Writing to file '/sys/devices/system/cpu/cpu1/cpufreq/scaling_governor' error: '[Errno 19] No such device'
/var/log/tuned/tuned.log:2020-04-28 15:23:19,037 ERROR tuned.utils.commands: Writing to file '/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor' error: '[Errno 19] No such device'
...
應用啓動時指定JVM參數
java -jar -Xms128m -Xmx1024m -Xss512k -XX:PermSize=128m -XX:MaxPermSize=64m -XX:NewSize=64m -XX:MaxNewSize=256m arthas-demo.jar
,如:
[root@localhost ~]# java -jar -Xms128m -Xmx1024m -Xss512k -XX:PermSize=128m -XX:MaxPermSize=64m -XX:NewSize=64m -XX:MaxNewSize=256m arthas-demo.jar
OpenJDK 64-Bit Server VM warning: ignoring option PermSize=128m; support was removed in 8.0
OpenJDK 64-Bit Server VM warning: ignoring option MaxPermSize=64m; support was removed in 8.0
157518=2*3*3*3*2917
illegalArgumentCount: 1, number is: -187733, need >= 2
illegalArgumentCount: 2, number is: -102156, need >= 2
173379=3*57793
總結
在使用linux命令時,如果想看幫助可以使用--help
或者man
查看幫助信息:
[root@localhost ~]# grep --help
用法: grep [選項]... PATTERN [FILE]...
在每個 FILE 或是標準輸入中查找 PATTERN。
默認的 PATTERN 是一個基本正則表達式(縮寫爲 BRE)。
例如: grep -i 'hello world' menu.h main.c
...
[root@localhost ~]# man grep
GREP(1) General Commands Manual GREP(1)
NAME
grep, egrep, fgrep - 打印匹配給定模式的行
總覽 SYNOPSIS
grep [options] PATTERN [FILE...]
grep [options] [-e PATTERN | -f FILE] [FILE...]
描述 DESCRIPTION
Grep 搜索以 FILE 命名的文件輸入 (或者是標準輸入,如果沒有指定文件名,或者給出的文件名是 - 的話),尋找含有與給定的模式 PATTERN
...
類別 | 監控命令 | 描述 | 備註 |
---|---|---|---|
內存瓶頸 | free | 查看內存使用 | |
vmstat 3(間隔時間) 100(監控次數) | 查看swap in/out詳細定位是否存在性能瓶頸 | 推薦使用 | |
sar -r 3 | 和free命令類似,查看內存的使用情況,但是不包含swap的情況 | ||
cpu瓶頸 | top -H | 按照cpu消耗高低進行排序 | |
ps -Lp 進程號 cu | 查看某個進程的cpu消耗排序 | ||
cat /proc/cpuinfo |grep 'processor'|wc -l | 查看cpu核數 | ||
top | 查看cpu總體消耗,包括分項消耗如user,system,idle,nice等消耗 | ||
top 然後shift+h:顯示java線程,然後shift+M:按照內存使用進行排序;shift+P:按照cpu時間排序;shift+T:按照cpu累計使用時間排序多核cpu,按“1”進入top視圖 | 專項性能排查,多核CPU主要看CUP各個內核的負載情況 | ||
sar -u 3(間隔時間) | 查看cpu總體消耗佔比 | ||
sar -q | 查看cpu load | ||
top -b -n 1 | awk '{if (NR<=7)print;else if($8=="D"){print;count++}}END{print "Total status D:"count}' | 計算在cpu load裏面的uninterruptedsleep的任務數量 uninterruptedsleep的任務會被計入cpu load,如磁盤堵塞 | ||
網絡瓶頸 | cat /var/log/messages | 查看內核日誌,查看是否丟包 | |
watch more /proc/net/dev | 用於定位丟包,錯包情況,以便看網絡瓶頸 | 重點關注drop(包被丟棄)和網絡包傳送的總量,不要超過網絡上限 | |
sar -n SOCK | 查看網絡流量 | ||
netstat -na|grep ESTABLISHED|wc -l | 查看tcp連接成功狀態的數量 | 此命令特別消耗cpu,不適合進行長時間監控數據收集 | |
netstat -na|awk'{print $6}'|sort |uniq -c |sort -nr | 看tcp各個狀態數量 | ||
netstat -i | 查看網絡錯誤 | ||
ss state ESTABLISHED| wc -l | 更高效地統計tcp連接狀態爲ESTABLISHED的數量 | ||
cat /proc/net/snmp | 查看和分析240秒內網絡包量,流量,錯包,丟包 | 用於計算重傳率tcpetr=RetransSegs/OutSegs |
|
ping $ip | 測試網絡性能 | ||
traceroute $ip | 查看路由經過的地址 | 常用於定位網絡在各個路由區段的耗時 | |
dig $域名 | 查看域名解析地址 | ||
dmesg | 查看系統內核日誌 | ||
磁盤瓶頸 | iostat -x -k -d 1 | 詳細列出磁盤的讀寫情況 | 當看到I/O等待時間所佔CPU時間的比重很高的時候,首先要檢查的就是機器是否正在大量使用交換空間,同時關注iowait佔比cpu的消耗是否很大,如果大說明磁盤存在大的瓶頸,同時關注await,表示磁盤的響應時間以便小於5ms |
iostat -x | 查看系統各個磁盤的讀寫性能 | 重點關注await和iowait的cpu佔比 | |
iotop | 查看哪個進程在大量讀取IO | 一般先通過iostat查看是否存在io瓶頸,再定位哪個進程在大量讀取IO | |
df -hl | 查看磁盤剩餘空間 | ||
du -sh | 查看磁盤使用了多少空間 | ||
應用瓶頸 | ps -ef | grep java | 查看某個進程的id號 |
ps -ef | grep httpd| wc -l | 查看特定進程的數量 | ||
cat *** .log | grep *** Exception| wc -l | 統計日誌文件中包含特定異常數量 | ||
jstack -l pid | 用於查看線程是否存在死鎖 | ||
awk'{print $8}' 2017-05-22-access_log|egrep '301|302'| wc -l | 統計log中301、302狀態碼的行數,$8表示第八列是狀態碼,可以根據實際情況更改 | 常用於應用故障定位 | |
grep 'wholesaleProductDetailNew' cookie_log | awk '{if($10=="200")}'print}' | awk 'print $12' | more | 打印包含特定數據的12列數據 | |
grep "2017:05:22" cookielog | awk '($12>0.3){print 8}' | sort > 目錄地址 | 對apache或者nginx訪問log進行響應時間排序,$12表示cookie log中的12列表示響應時間 用於排查是否是由於是某些訪問超長造成整體的RT變長 | ||
grep -v 'HTTP/1.1" 200' | 取出非200響應碼的URL | ||
pgm -A -f $應用集羣名稱 "grep "'301' log文件地址 | wc -l" | 查看整個集羣的log中301狀態碼的數量 | ||
ps -efL | grep [PID] | wc -l | 查看某個進程創建的線程數 | ||
find / -type f -name " * .log" | xargs grep "ERROR" | 統計所有的log文件中,包含Error字符的行 | 這個在排查問題過程中比較有用 | |
jstat -gc [pid] | 查看gc情況 | ||
jstat -gcnew [pid] | 查看young區的內存使用情況,包括MTT(最大交互次數就被交換到old區),TT是目前已經交換的次數 | ||
jstat -gcold | 查看old區的內存使用情況 | ||
jmap -J-d64 -dump:format=b,file=dump.bin PID | dump出內存快照 | -J-d64防止jmap導致虛擬機crash(jdk6有bug) | |
-XX:+HeapDumpOnOutOfMemeryError | 在java啓動時加入,當出現內存溢出時,存儲內存快照 | ||
jmap -histo [pid] | 按照對象內存大小排序 | 注意會導致full gc | |
gcore [pid] | 導出完成的內存快照 | 通常和jmap -permstat /opt/ ** /java gcore.bin 一起使用,將core dump轉換成heap dump |
|
-XX:HeapDumpPath=/home/logs -Xloggc:/home/log/gc.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps | 在Java啓動參數中加入,打印gc日誌 | ||
-server -Xms4000m -Xmx4000m -Xmn1500m -Xss256k -XX:PermSize=340m -XX:MaxPermSize=340m -XX:+UseConcMarkSweepGC | 調整JVM堆大小 | xss是棧大小 |
往期推薦
喜歡的這裏報道
↘↘↘
本文分享自微信公衆號 - 程序猿DD(didispace)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。