如果你的Linux服務(wù)器突然負(fù)載暴增引颈,告警短信快發(fā)爆你的手機(jī),如何在最短時(shí)間內(nèi)找出Linux性能問(wèn)題所在?來(lái)看Netflix性能工程團(tuán)隊(duì)的這篇博文,看它們通過(guò)十條命令在一分鐘內(nèi)對(duì)機(jī)器性能問(wèn)題進(jìn)行診斷粟害。
概述
通過(guò)執(zhí)行以下命令,可以在1分鐘內(nèi)對(duì)系統(tǒng)資源使用情況有個(gè)大致的了解颤芬。
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
其中一些命令需要安裝sysstat包悲幅,有一些由procps包提供。這些命令的輸出站蝠,有助于快速定位性能瓶頸汰具,檢查出所有資源(CPU、內(nèi)存菱魔、磁盤IO等)的利用率(utilization)留荔、飽和度(saturation)和錯(cuò)誤(error)度量,也就是所謂的USE方法澜倦。
下面我們來(lái)逐一介紹下這些命令聚蝶,有關(guān)這些命令更多的參數(shù)和說(shuō)明,請(qǐng)參照命令的手冊(cè)藻治。
uptime
$ uptime
23:51:26 up 21:31, 1 user, load average: 30.02, 26.43, 19.02
這個(gè)命令可以快速查看機(jī)器的負(fù)載情況碘勉。在Linux系統(tǒng)中,這些數(shù)據(jù)表示等待CPU資源的進(jìn)程和阻塞在不可中斷IO進(jìn)程(進(jìn)程狀態(tài)為D)的數(shù)量桩卵。這些數(shù)據(jù)可以讓我們對(duì)系統(tǒng)資源使用有一個(gè)宏觀的了解验靡。
命令的輸出分別表示1分鐘、5分鐘吸占、15分鐘的平均負(fù)載情況晴叨。通過(guò)這三個(gè)數(shù)據(jù),可以了解服務(wù)器負(fù)載是在趨于緊張還是區(qū)域緩解矾屯。如果1分鐘平均負(fù)載很高兼蕊,而15分鐘平均負(fù)載很低,說(shuō)明服務(wù)器正在命令高負(fù)載情況件蚕,需要進(jìn)一步排查CPU資源都消耗在了哪里孙技。反之,如果15分鐘平均負(fù)載很高排作,1分鐘平均負(fù)載較低牵啦,則有可能是CPU資源緊張時(shí)刻已經(jīng)過(guò)去。
上面例子中的輸出妄痪,可以看見(jiàn)最近1分鐘的平均負(fù)載非常高哈雏,且遠(yuǎn)高于最近15分鐘負(fù)載,因此我們需要繼續(xù)排查當(dāng)前系統(tǒng)中有什么進(jìn)程消耗了大量的資源∩驯瘢可以通過(guò)下文將會(huì)介紹的vmstat土浸、mpstat等命令進(jìn)一步排查。
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.
該命令會(huì)輸出系統(tǒng)日志的最后10行彭羹。示例中的輸出黄伊,可以看見(jiàn)一次內(nèi)核的oom kill和一次TCP丟包。這些日志可以幫助排查性能問(wèn)題派殷。千萬(wàn)不要忘了這一步还最。
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) 命令,每行會(huì)輸出一些系統(tǒng)核心指標(biāo)毡惜,這些指標(biāo)可以讓我們更詳細(xì)的了解系統(tǒng)狀態(tài)拓轻。后面跟的參數(shù)1,表示每秒輸出一次統(tǒng)計(jì)信息虱黄,表頭提示了每一列的含義悦即,這幾介紹一些和性能調(diào)優(yōu)相關(guān)的列:
- r:等待在CPU資源的進(jìn)程數(shù)。這個(gè)數(shù)據(jù)比平均負(fù)載更加能夠體現(xiàn)CPU負(fù)載情況橱乱,數(shù)據(jù)中不包含等待IO的進(jìn)程辜梳。如果這個(gè)數(shù)值大于機(jī)器CPU核數(shù),那么機(jī)器的CPU資源已經(jīng)飽和泳叠。
- free:系統(tǒng)可用內(nèi)存數(shù)(以千字節(jié)為單位)作瞄,如果剩余內(nèi)存不足,也會(huì)導(dǎo)致系統(tǒng)性能問(wèn)題危纫。下文介紹到的free命令宗挥,可以更詳細(xì)的了解系統(tǒng)內(nèi)存的使用情況。
- si, so:交換區(qū)寫(xiě)入和讀取的數(shù)量种蝶。如果這個(gè)數(shù)據(jù)不為0契耿,說(shuō)明系統(tǒng)已經(jīng)在使用交換區(qū)(swap),機(jī)器物理內(nèi)存已經(jīng)不足螃征。
- us, sy, id, wa, st:這些都代表了CPU時(shí)間的消耗搪桂,它們分別表示用戶時(shí)間(user)、系統(tǒng)(內(nèi)核)時(shí)間(sys)盯滚、空閑時(shí)間(idle)踢械、IO等待時(shí)間(wait)和被偷走的時(shí)間(stolen,一般被其他虛擬機(jī)消耗)魄藕。
上述這些CPU時(shí)間内列,可以讓我們很快了解CPU是否出于繁忙狀態(tài)。一般情況下背率,如果用戶時(shí)間和系統(tǒng)時(shí)間相加非常大话瞧,CPU出于忙于執(zhí)行指令嫩与。如果IO等待時(shí)間很長(zhǎng),那么系統(tǒng)的瓶頸可能在磁盤IO移稳。
示例命令的輸出可以看見(jiàn)透乾,大量CPU時(shí)間消耗在用戶態(tài)消略,也就是用戶應(yīng)用程序消耗了CPU時(shí)間。這不一定是性能問(wèn)題钦购,需要結(jié)合r隊(duì)列翻翩,一起分析都许。
mpstat -P ALL 1
$ mpstat -P ALL 1Linux 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è)CPU的占用情況,如果有一個(gè)CPU占用率特別高嫂冻,那么有可能是一個(gè)單線程應(yīng)用程序引起的胶征。
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
pidstat命令輸出進(jìn)程的CPU占用率,該命令會(huì)持續(xù)輸出桨仿,并且不會(huì)覆蓋之前的數(shù)據(jù)睛低,可以方便觀察系統(tǒng)動(dòng)態(tài)。如上的輸出服傍,可以看見(jiàn)兩個(gè)JAVA進(jìn)程占用了將近1600%的CPU時(shí)間钱雷,既消耗了大約16個(gè)CPU核心的運(yùn)算資源。
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
[...]
iostat命令主要用于查看機(jī)器磁盤IO情況吹零。該命令輸出的列罩抗,主要含義是:
- r/s, w/s, rkB/s, wkB/s:分別表示每秒讀寫(xiě)次數(shù)和每秒讀寫(xiě)數(shù)據(jù)量(千字節(jié))。讀寫(xiě)量過(guò)大灿椅,可能會(huì)引起性能問(wèn)題套蒂。
- await:IO操作的平均等待時(shí)間,單位是毫秒茫蛹。這是應(yīng)用程序在和磁盤交互時(shí)操刀,需要消耗的時(shí)間,包括IO等待和實(shí)際操作的耗時(shí)婴洼。如果這個(gè)數(shù)值過(guò)大骨坑,可能是硬件設(shè)備遇到了瓶頸或者出現(xiàn)故障。
- avgqu-sz:向設(shè)備發(fā)出的請(qǐng)求平均數(shù)量窃蹋。如果這個(gè)數(shù)值大于1卡啰,可能是硬件設(shè)備已經(jīng)飽和(部分前端硬件設(shè)備支持并行寫(xiě)入)。
- %util:設(shè)備利用率警没。這個(gè)數(shù)值表示設(shè)備的繁忙程度匈辱,經(jīng)驗(yàn)值是如果超過(guò)60,可能會(huì)影響IO性能(可以參照IO操作平均等待時(shí)間)杀迹。如果到達(dá)100%亡脸,說(shuō)明硬件設(shè)備已經(jīng)飽和。
如果顯示的是邏輯設(shè)備的數(shù)據(jù),那么設(shè)備利用率不代表后端實(shí)際的硬件設(shè)備已經(jīng)飽和浅碾。值得注意的是大州,即使IO性能不理想,也不一定意味這應(yīng)用程序性能會(huì)不好垂谢,可以利用諸如預(yù)讀取厦画、寫(xiě)緩存等策略提升應(yīng)用性能。
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
free命令可以查看系統(tǒng)內(nèi)存的使用情況滥朱,-m參數(shù)表示按照兆字節(jié)展示根暑。最后兩列分別表示用于IO緩存的內(nèi)存數(shù),和用于文件系統(tǒng)頁(yè)緩存的內(nèi)存數(shù)徙邻。需要注意的是排嫌,第二行-/+ buffers/cache,看上去緩存占用了大量?jī)?nèi)存空間缰犁。這是Linux系統(tǒng)的內(nèi)存使用策略淳地,盡可能的利用內(nèi)存,如果應(yīng)用程序需要內(nèi)存帅容,這部分內(nèi)存會(huì)立即被回收并分配給應(yīng)用程序颇象。因此,這部分內(nèi)存一般也被當(dāng)成是可用內(nèi)存丰嘉。
如果可用內(nèi)存非常少夯到,系統(tǒng)可能會(huì)動(dòng)用交換區(qū)(如果配置了的話),這樣會(huì)增加IO開(kāi)銷(可以在iostat命令中提現(xiàn))饮亏,降低系統(tǒng)性能耍贾。
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
sar命令在這里可以查看網(wǎng)絡(luò)設(shè)備的吞吐率。在排查性能問(wèn)題時(shí)路幸,可以通過(guò)網(wǎng)絡(luò)設(shè)備的吞吐量荐开,判斷網(wǎng)絡(luò)設(shè)備是否已經(jīng)飽和。如示例輸出中简肴,eth0網(wǎng)卡設(shè)備晃听,吞吐率大概在22 Mbytes/s,既176 Mbits/sec砰识,沒(méi)有達(dá)到1Gbit/sec的硬件上限能扒。
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
sar命令在這里用于查看TCP連接狀態(tài),其中包括:
- active/s:每秒本地發(fā)起的TCP連接數(shù)辫狼,既通過(guò)connect調(diào)用創(chuàng)建的TCP連接初斑;
- passive/s:每秒遠(yuǎn)程發(fā)起的TCP連接數(shù),即通過(guò)accept調(diào)用創(chuàng)建的TCP連接膨处;
- retrans/s:每秒TCP重傳數(shù)量见秤;
TCP連接數(shù)可以用來(lái)判斷性能問(wèn)題是否由于建立了過(guò)多的連接砂竖,進(jìn)一步可以判斷是主動(dòng)發(fā)起的連接,還是被動(dòng)接受的連接鹃答。TCP重傳可能是因?yàn)榫W(wǎng)絡(luò)環(huán)境惡劣乎澄,或者服務(wù)器壓力過(guò)大導(dǎo)致丟包。
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
root 20 0 0.227t 0.012t 18748 S 3090 5.2 29812:58 java
root 20 0 2722544 64640 44232 S 23.5 0.0 233:35.37 mesos-slave
titancl+ 20 0 24344 2332 1172 R 1.0 0.0 0:00.07 top
root 20 0 38.227g 547004 49996 S 0.7 0.2 2:02.74 java
root 20 0 20.015g 2.682g 16836 S 0.3 1.1 33:14.42 java
root 20 0 33620 2920 1496 S 0.0 0.0 0:03.82 init
root 20 0 0 0 0 S 0.0 0.0 0:00.02 kthreadd
root 20 0 0 0 0 S 0.0 0.0 0:05.35 ksoftirqd/0
root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
root 20 0 0 0 0 S 0.0 0.0 0:06.94 kworker/u256:0
root 20 0 0 0 0 S 0.0 0.0 2:38.05 rcu_sched
top命令包含了前面好幾個(gè)命令的檢查的內(nèi)容测摔。比如系統(tǒng)負(fù)載情況(uptime)置济、系統(tǒng)內(nèi)存使用情況(free)、系統(tǒng)CPU使用情況(vmstat)等避咆。因此通過(guò)這個(gè)命令舟肉,可以相對(duì)全面的查看系統(tǒng)負(fù)載的來(lái)源。同時(shí)查库,top命令支持排序,可以按照不同的列排序黄琼,方便查找出諸如內(nèi)存占用最多的進(jìn)程樊销、CPU占用率最高的進(jìn)程等。
但是脏款,top命令相對(duì)于前面一些命令围苫,輸出是一個(gè)瞬間值,如果不持續(xù)盯著撤师,可能會(huì)錯(cuò)過(guò)一些線索剂府。這時(shí)可能需要暫停top命令刷新,來(lái)記錄和比對(duì)數(shù)據(jù)剃盾。
總結(jié)
排查L(zhǎng)inux服務(wù)器性能問(wèn)題還有很多工具腺占,上面介紹的一些命令,可以幫助我們快速的定位問(wèn)題痒谴。例如前面的示例輸出衰伯,多個(gè)證據(jù)證明有JAVA進(jìn)程占用了大量CPU資源,之后的性能調(diào)優(yōu)就可以針對(duì)應(yīng)用程序進(jìn)行积蔚。