26. 60s快速定位服務(wù)器性能問(wèn)題

60s迅速發(fā)現(xiàn)性能問(wèn)題

  • uptime
  • dmesg | tail
  • vmstat 1
  • mpstat -P ALL 1
  • pidstat 1
  • iostat -xz 1
  • free -m
  • sar -n DEV 1
  • sar -n TCP,ETCP 1
  • top

1、uptime

$ uptime
23:51:26 up 21:31, 1 user, load average: 30.02, 26.43, 19.02

這是一種用來(lái)快速查看系統(tǒng)平均負(fù)載的方法,它表明了系統(tǒng)中有多少要運(yùn)行的任務(wù)(進(jìn)程)。在 Linux 系統(tǒng)中,這些數(shù)字包含了需要在 CPU 中運(yùn)行的進(jìn)程以及正在等待 I/O(通常是磁盤 I/O)的進(jìn)程。它僅僅是對(duì)系統(tǒng)負(fù)載的一個(gè)粗略展示,稍微看下即可。你還需要其他工具來(lái)進(jìn)一步了解具體情況。

這三個(gè)數(shù)字展示的是一分鐘、五分鐘和十五分鐘內(nèi)系統(tǒng)的負(fù)載總量平均值按照指數(shù)比例壓縮得到的結(jié)果。從中我們可以看到系統(tǒng)的負(fù)載是如何隨時(shí)間變化的。比方你在檢查一個(gè)問(wèn)題,然后看到 1 分鐘對(duì)應(yīng)的值遠(yuǎn)小于 15 分鐘的值,那么可能說(shuō)明這個(gè)問(wèn)題已經(jīng)過(guò)去了,你沒(méi)能及時(shí)觀察到。

在上面這個(gè)例子中,系統(tǒng)負(fù)載在隨著時(shí)間增加,因?yàn)樽罱环昼姷呢?fù)載值超過(guò)了 30,而 15 分鐘的平均負(fù)載則只有 19。這樣顯著的差距包含了很多含義,比方 CPU 負(fù)載。若要進(jìn)一步確認(rèn)的話,則要運(yùn)行 vmstat 或 mpstat 命令。

2、dmesg | tail

$ dmesg | tail
[1880957.563150] perl invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0
[...]
[1880957.563400] Out of memory: Kill process 18694 (perl) score 246 or sacrifice child
[1880957.563408] Killed process 18694 (perl) total-vm:1972392kB, anon-rss:1953348kB, file-rss:0kB
[2320864.954447] TCP: Possible SYN flooding on port 7001. Dropping request.  Check SNMP counters.

這條命令顯式了最近的 10 條系統(tǒng)消息,如果它們存在的話。查找能夠?qū)е滦阅軉?wèn)題的錯(cuò)誤。上面的例子包含了 oom-killer,以及 TCP 丟棄一個(gè)請(qǐng)求。千萬(wàn)不要錯(cuò)過(guò)這一步!dmesg 命令永遠(yuǎn)值得一試。

3、vmstat 1

$ 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
34  0    0 200889792  73708 591828    0    0     0     5    6   10 96  1  3  0  0
32  0    0 200889920  73708 591860    0    0     0   592 13284 4282 98  1  1  0  0
32  0    0 200890112  73708 591860    0    0     0     0 9501 2154 99  1  0  0  0
32  0    0 200889568  73712 591856    0    0     0    48 11900 2459 99  0  0  0  0
32  0    0 200890208  73712 591860    0    0     0     0 15898 4840 98  1  1  0  0

vmstat(8) 是虛擬內(nèi)存統(tǒng)計(jì)的簡(jiǎn)稱,其是一個(gè)常用工具(幾十年前為了 BSD 所創(chuàng)建)。其在每行打印一條關(guān)鍵的服務(wù)器的統(tǒng)計(jì)摘要。

vmstat 命令指定一個(gè)參數(shù) 1 運(yùn)行,來(lái)打印每一秒的統(tǒng)計(jì)摘要。(這個(gè)版本的 vmstat)輸出的第一行的那些列,顯式的是開(kāi)機(jī)以來(lái)的平均值,而不是前一秒的值?,F(xiàn)在,我們跳過(guò)第一行,除非你想要了解并記住每一列。

檢查這些列:

  • r:CPU 中正在運(yùn)行和等待運(yùn)行的進(jìn)程的數(shù)量。其提供了一個(gè)比平均負(fù)載更好的信號(hào)來(lái)確定 CPU 是否飽和,因?yàn)槠洳话?I/O。解釋:“r”的值大于了 CPU 的數(shù)量就表示已經(jīng)飽和了。

  • free:以 kb 為單位顯式的空閑內(nèi)存。如果數(shù)字位數(shù)很多,說(shuō)明你有足夠的空閑內(nèi)存。“free -m” 命令,是下面的第七個(gè)命令,其可以更好的說(shuō)明空閑內(nèi)存的狀態(tài)。

  • si, so:Swap-ins 和 swap-outs。如果它們不是零,則代表你的內(nèi)存不足了。

  • us, sy, id, wa, st:這些都是平均了所有 CPU 的 CPU 分解時(shí)間。它們分別是用戶時(shí)間(user)、系統(tǒng)時(shí)間(內(nèi)核)(system)、空閑(idle)、等待 I/O(wait)、以及占用時(shí)間(stolen)(被其他訪客,或使用 Xen,訪客自己獨(dú)立的驅(qū)動(dòng)域)。

CPU 分解時(shí)間將會(huì)通過(guò)用戶時(shí)間加系統(tǒng)時(shí)間確認(rèn) CPU 是否為忙碌狀態(tài)。等待 I/O 的時(shí)間一直不變則表明了一個(gè)磁盤瓶頸;這就是 CPU 的閑置,因?yàn)槿蝿?wù)都阻塞在等待掛起磁盤 I/O 上了。你可以把等待 I/O 當(dāng)成是 CPU 閑置的另一種形式,其給出了為什么 CPU 閑置的一個(gè)線索。

對(duì)于 I/O 處理來(lái)說(shuō),系統(tǒng)時(shí)間是很重要的。一個(gè)高于 20% 的平均系統(tǒng)時(shí)間,可以值得進(jìn)一步的探討:也許內(nèi)核在處理 I/O 時(shí)效率太低了。

在上面的例子中,CPU 時(shí)間幾乎完全花在了用戶級(jí),表明應(yīng)用程序占用了太多 CPU 時(shí)間。而 CPU 的平均使用率也在 90% 以上。這不一定是一個(gè)問(wèn)題;檢查一下“r”列中的飽和度。

4、 mpstat -P ALL 1

$ mpstat -P ALL 1
Linux 3.13.0-49-generic (titanclusters-xxxxx)  07/14/2015  _x86_64_ (32 CPU)

07:38:49 PM  CPU   %usr  %nice   %sys %iowait   %irq  %soft  %steal  %guest  %gnice  %idle
07:38:50 PM  all  98.47   0.00   0.75    0.00   0.00   0.00    0.00    0.00    0.00   0.78
07:38:50 PM    0  96.04   0.00   2.97    0.00   0.00   0.00    0.00    0.00    0.00   0.99
07:38:50 PM    1  97.00   0.00   1.00    0.00   0.00   0.00    0.00    0.00    0.00   2.00
07:38:50 PM    2  98.00   0.00   1.00    0.00   0.00   0.00    0.00    0.00    0.00   1.00
07:38:50 PM    3  96.97   0.00   0.00    0.00   0.00   0.00    0.00    0.00    0.00   3.03
[...]

這個(gè)命令打印每個(gè) CPU 的 CPU 分解時(shí)間,其可用于對(duì)一個(gè)不均衡的使用情況進(jìn)行檢查。一個(gè)單獨(dú) CPU 很忙碌則代表了正在運(yùn)行一個(gè)單線程的應(yīng)用程序。

5、 pidstat 1

$ pidstat 1
Linux 3.13.0-49-generic (titanclusters-xxxxx)  07/14/2015    _x86_64_    (32 CPU)

07:41:02 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
07:41:03 PM     0         9    0.00    0.94    0.00    0.94     1  rcuos/0
07:41:03 PM     0      4214    5.66    5.66    0.00   11.32    15  mesos-slave
07:41:03 PM     0      4354    0.94    0.94    0.00    1.89     8  java
07:41:03 PM     0      6521 1596.23    1.89    0.00 1598.11    27  java
07:41:03 PM     0      6564 1571.70    7.55    0.00 1579.25    28  java
07:41:03 PM 60004     60154    0.94    4.72    0.00    5.66     9  pidstat

07:41:03 PM   UID       PID    %usr %system  %guest    %CPU   CPU  Command
07:41:04 PM     0      4214    6.00    2.00    0.00    8.00    15  mesos-slave
07:41:04 PM     0      6521 1590.00    1.00    0.00 1591.00    27  java
07:41:04 PM     0      6564 1573.00   10.00    0.00 1583.00    28  java
07:41:04 PM   108      6718    1.00    0.00    0.00    1.00     0  snmp-pass
07:41:04 PM 60004     60154    1.00    4.00    0.00    5.00     9  pidstat
^C

pidstat 命令有點(diǎn)像 top 命令對(duì)每個(gè)進(jìn)程的統(tǒng)計(jì)摘要,但循環(huán)打印一個(gè)滾動(dòng)的統(tǒng)計(jì)摘要來(lái)代替 top 的刷屏。其可用于實(shí)時(shí)查看,同時(shí)也可將你所看到的東西(復(fù)制粘貼)到你的調(diào)查記錄中。

上面的例子表明兩個(gè) Java 進(jìn)程正在消耗 CPU。%CPU 這列是所有 CPU 合計(jì)的;1591% 表示這個(gè) Java 進(jìn)程消耗了將近 16 個(gè) CPU。

6、 iostat -xz 1

$ iostat -xz 1
Linux 3.13.0-49-generic (titanclusters-xxxxx)  07/14/2015  _x86_64_ (32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          73.96    0.00    3.73    0.03    0.06   22.21

Device:   rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
xvda        0.00     0.23    0.21    0.18     4.52     2.08    34.37     0.00    9.98   13.80    5.42   2.44   0.09
xvdb        0.01     0.00    1.02    8.94   127.97   598.53   145.79     0.00    0.43    1.78    0.28   0.25   0.25
xvdc        0.01     0.00    1.02    8.86   127.79   595.94   146.50     0.00    0.45    1.82    0.30   0.27   0.26
dm-0        0.00     0.00    0.69    2.32    10.47    31.69    28.01     0.01    3.23    0.71    3.98   0.13   0.04
dm-1        0.00     0.00    0.00    0.94     0.01     3.78     8.00     0.33  345.84    0.04  346.81   0.01   0.00
dm-2        0.00     0.00    0.09    0.07     1.35     0.36    22.50     0.00    2.55    0.23    5.62   1.78   0.03
[...]
^C

這是用于查看塊設(shè)備(磁盤)情況的一個(gè)很棒的工具,無(wú)論是對(duì)工作負(fù)載還是性能表現(xiàn)來(lái)說(shuō)。查看個(gè)列:

  • r/s, w/s, rkB/s, wkB/s:這些分別代表該設(shè)備每秒的讀次數(shù)、寫次數(shù)、讀取 kb 數(shù),和寫入 kb 數(shù)。這些用于描述工作負(fù)載。性能問(wèn)題可能僅僅是由于施加了過(guò)大的負(fù)載。

  • await:以毫秒為單位的 I/O 平均消耗時(shí)間。這是應(yīng)用程序消耗的實(shí)際時(shí)間,因?yàn)樗伺抨?duì)時(shí)間和處理時(shí)間。比預(yù)期更大的平均時(shí)間可能意味著設(shè)備的飽和,或設(shè)備出了問(wèn)題。

  • avgqu-sz:向設(shè)備發(fā)出的請(qǐng)求的平均數(shù)量。值大于 1 說(shuō)明已經(jīng)飽和了(雖說(shuō)設(shè)備可以并行處理請(qǐng)求,尤其是由多個(gè)磁盤組成的虛擬設(shè)備。)

  • %util:設(shè)備利用率。這個(gè)值是一個(gè)顯示出該設(shè)備在工作時(shí)每秒處于忙碌狀態(tài)的百分比。若值大于 60%,通常表明性能不佳(可以從 await 中看出),雖然它取決于設(shè)備本身。值接近 100% 通常意味著已飽和。

如果該存儲(chǔ)設(shè)備是一個(gè)面向很多后端磁盤的邏輯磁盤設(shè)備,則 100% 利用率可能只是意味著當(dāng)前正在處理某些 I/O 占用,然而,后端磁盤可能遠(yuǎn)未飽和,并且可能能夠處理更多的工作。

請(qǐng)記住,磁盤 I/O 性能較差不一定是程序的問(wèn)題。許多技術(shù)通常是異步 I/O,使應(yīng)用程序不會(huì)被阻塞并遭受延遲(例如,預(yù)讀,以及寫緩沖)。

7、 free -m

$ free -m
             total       used       free     shared    buffers     cached
Mem:        245998      24545     221453         83         59        541
-/+ buffers/cache:      23944     222053
Swap:            0          0          0

右邊的兩列顯式:

  • buffers:用于塊設(shè)備 I/O 的緩沖區(qū)緩存。

  • cached:用于文件系統(tǒng)的頁(yè)面緩存。

我們只是想要檢查這些不接近零的大小,其可能會(huì)導(dǎo)致更高磁盤 I/O(使用 iostat 確認(rèn)),和更糟糕的性能。上面的例子看起來(lái)還不錯(cuò),每一列均有很多 M 個(gè)大小。

比起第一行,-/+ buffers/cache 提供的內(nèi)存使用量會(huì)更加準(zhǔn)確些。Linux 會(huì)把暫時(shí)用不上的內(nèi)存用作緩存,一旦應(yīng)用需要的時(shí)候就立刻重新分配給它。所以部分被用作緩存的內(nèi)存其實(shí)也算是空閑的內(nèi)存。為了解釋這一點(diǎn), 甚至有人專門建了個(gè)網(wǎng)站: linuxatemyram。

如果你在 Linux 上安裝了 ZFS,這一點(diǎn)會(huì)變得更加困惑,因?yàn)?ZFS 它自己的文件系統(tǒng)緩存不算入free -m。有時(shí)候發(fā)現(xiàn)系統(tǒng)已經(jīng)沒(méi)有多少空閑內(nèi)存可用了,其實(shí)內(nèi)存卻都待在 ZFS 的緩存里。

8、 sar -n DEV 1

$ sar -n DEV 1
Linux 3.13.0-49-generic (titanclusters-xxxxx)  07/14/2015     _x86_64_    (32 CPU)

12:16:48 AM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
12:16:49 AM      eth0  18763.00   5032.00  20686.42    478.30      0.00      0.00      0.00      0.00
12:16:49 AM        lo     14.00     14.00      1.36      1.36      0.00      0.00      0.00      0.00
12:16:49 AM   docker0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00

12:16:49 AM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
12:16:50 AM      eth0  19763.00   5101.00  21999.10    482.56      0.00      0.00      0.00      0.00
12:16:50 AM        lo     20.00     20.00      3.25      3.25      0.00      0.00      0.00      0.00
12:16:50 AM   docker0      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
^C

這個(gè)工具可以被用來(lái)檢查網(wǎng)絡(luò)接口的吞吐量:rxkB/s 和 txkB/s,以及是否達(dá)到限額。上面的例子中,eth0 接收的流量達(dá)到 22Mbytes/s,也即 176Mbits/sec(限額是 1Gbit/sec)

我們用的版本中還提供了 %ifutil 作為設(shè)備使用率(接收和發(fā)送的最大值)的指標(biāo)。我們也可以用 Brendan 的 nicstat 工具計(jì)量這個(gè)值。一如 nicstat,sar 顯示的這個(gè)值是很難精確取得的,在這個(gè)例子里面,它就沒(méi)在正常的工作(0.00)。

9、 sar -n TCP,ETCP 1

$ sar -n TCP,ETCP 1
Linux 3.13.0-49-generic (titanclusters-xxxxx)  07/14/2015    _x86_64_    (32 CPU)

12:17:19 AM  active/s passive/s    iseg/s    oseg/s
12:17:20 AM      1.00      0.00  10233.00  18846.00

12:17:19 AM  atmptf/s  estres/s retrans/s isegerr/s   orsts/s
12:17:20 AM      0.00      0.00      0.00      0.00      0.00

12:17:20 AM  active/s passive/s    iseg/s    oseg/s
12:17:21 AM      1.00      0.00   8359.00   6039.00

12:17:20 AM  atmptf/s  estres/s retrans/s isegerr/s   orsts/s
12:17:21 AM      0.00      0.00      0.00      0.00      0.00
^C

這是一些關(guān)鍵的 TCP 指標(biāo)的匯總視圖。這些包括:

  • active/s:每秒本地發(fā)起 TCP 連接數(shù)(例如,通過(guò) connect())。

  • passive/s:每秒遠(yuǎn)程發(fā)起的 TCP 連接數(shù)(例如,通過(guò) accept())。

  • retrans/s:每秒重傳 TCP 次數(shù)。

  • active 和 passive 的連接數(shù)往往對(duì)于描述一個(gè)粗略衡量服務(wù)器負(fù)載是非常有用的:新接受的連接數(shù)(passive),下行連接數(shù)(active)??梢岳斫鉃?active 連接是對(duì)外的,而 passive 連接是對(duì)內(nèi)的,雖然嚴(yán)格來(lái)說(shuō)并不完全正確(例如,一個(gè) localhost 到 localhost 的連接)。

重傳是出現(xiàn)一個(gè)網(wǎng)絡(luò)和服務(wù)器問(wèn)題的一個(gè)征兆。其可能是由于一個(gè)不可靠的網(wǎng)絡(luò)(例如,公網(wǎng))造成的,或許也有可能是由于服務(wù)器過(guò)載并丟包。上面的例子顯示了每秒只有一個(gè)新的 TCP 連接。

10、 top

$ top
top - 00:15:40 up 21:56,  1 user,  load average: 31.09, 29.87, 29.92
Tasks: 871 total,   1 running, 868 sleeping,   0 stopped,   2 zombie
%Cpu(s): 96.8 us,  0.4 sy,  0.0 ni,  2.7 id,  0.1 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem:  25190241+total, 24921688 used, 22698073+free,    60448 buffers
KiB Swap:        0 total,        0 used,        0 free.   554208 cached Mem

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 20248 root      20   0  0.227t 0.012t  18748 S  3090  5.2  29812:58 java
  4213 root      20   0 2722544  64640  44232 S  23.5  0.0 233:35.37 mesos-slave
 66128 titancl+  20   0   24344   2332   1172 R   1.0  0.0   0:00.07 top
  5235 root      20   0 38.227g 547004  49996 S   0.7  0.2   2:02.74 java
  4299 root      20   0 20.015g 2.682g  16836 S   0.3  1.1  33:14.42 java
     1 root      20   0   33620   2920   1496 S   0.0  0.0   0:03.82 init
     2 root      20   0       0      0      0 S   0.0  0.0   0:00.02 kthreadd
     3 root      20   0       0      0      0 S   0.0  0.0   0:05.35 ksoftirqd/0
     5 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:06.94 kworker/u256:0
     8 root      20   0       0      0      0 S   0.0  0.0   2:38.05 rcu_sched

top 命令包含了很多我們之前已經(jīng)檢查過(guò)的指標(biāo)??梢苑奖愕膱?zhí)行它來(lái)查看相比于之前的命令輸出的結(jié)果有很大不同,這表明負(fù)載是可變的。

top 的一個(gè)缺點(diǎn)是,很難看到數(shù)據(jù)隨時(shí)間變動(dòng)的趨勢(shì)。vmstat 和 pidstat 提供的滾動(dòng)輸出會(huì)更清楚一些。如果你不以足夠快的速度暫停輸出(Ctrl-S 暫停,Ctrl-Q 繼續(xù)),一些間歇性問(wèn)題的線索也可能由于被清屏而丟失。

軟件測(cè)試汪簡(jiǎn)書地址
軟件測(cè)試汪博客地址

歡迎關(guān)注微信公眾號(hào):軟件測(cè)試汪。軟件測(cè)試交流群:809111560

轉(zhuǎn)載請(qǐng)注意出處,謝謝合作

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容