快速檢查單(Quick Reference Handbook,QRH)是飛行員在飛行過程當中依賴的重要指導性文件。前端
第一張飛行檢查單起源於一次嚴重的航空事故。1935年波音公司研製的一架新型轟炸機在試飛過程當中忽然墜機,致使2名機組人員遇難——包括一名最優秀的試飛員普洛耶爾·希爾少校。後來的調查結果分析,事故並非機械故障引發的,而是人爲失誤形成。新型飛機比以往的飛機更復雜,飛行員要管理4臺發動機,操控起落架、襟翼、電動配平調整片和恆速液壓變距螺旋槳等。由於忙於各類操做,希爾少校忘記了一項簡單卻很重要的工做 —— 在起飛前忘記對新設計的升降舵和方向舵實施解鎖。java
美國軍方組織飛行專家編制了一份飛行檢查單,將起飛、巡航、着陸和滑行各階段的重要步驟寫在一張索引卡片上。飛行員根據檢查單的提示檢查剎車是否鬆開,飛行儀表是否準確設定,機艙門窗是否徹底關閉,升降舵等控制面是否已經解鎖。linux
登錄一臺 Linux 服務器排查性能問題:開始一分鐘你該檢查哪些呢?ios
在 Netflix 咱們有一個龐大的 EC2 Linux集羣,也有許多性能分析工具用於監視和檢查它們的性能。它們包括用於雲監測的Atlas (工具代號) ,用於實例分析的 Vector (工具代號) 。儘管這些工具能幫助咱們解決大部分問題,咱們有時也須要登錄一臺實例、運行一些標準的 Linux 性能分析工具。在這篇文章,Netflix 性能工程團隊將向您展現:在開始的60秒鐘,利用標準的Linux命令行工具,執行一次充分的性能檢查。git
運行如下10個命令,你能夠在60秒內,得到系統資源利用率和進程運行狀況的總體概念。查看是否存在異常、評估飽和度,它們都很是易於理解,可用性強。飽和度表示資源還有多少負荷可讓它處理,而且可以展現請求隊列的長度或等待的時間。github
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
性能檢查的通常步驟docker
這些命令須要安裝sysstat包。這些命令輸出的指標,將幫助你掌握一些有效的方法:一整套尋找性能瓶頸的方法論。這些命令須要檢查全部資源的利用率、飽和度和錯誤信息(CPU、內存、磁盤等)。同時,當你檢查或排除一些資源的時候,須要注意在檢查過程當中,根據指標數據指引,逐步縮小目標範圍。後端
接下來的章節,將結合生產環境的案例演示這些命令。若是但願瞭解這些工具的詳細信息,能夠查閱它們的操做文檔。緩存
$ uptime 23:51:26up21:31, 1user, loadaverage:30.02,26.43,19.02
這是一個快速查看平均負載的方法,表示等待運行的任務(進程)數量。在Linux系統中,這些數字包含等待CPU運行的進程數,也包括不間斷I/O阻塞的進程數(一般是磁盤I/O)。它展現了一個資源負載(或需求)的總體概念,可是沒法理解其中的內涵,在沒有其它工具的狀況下。僅僅是一種快速查看手段而已。性能優化
這三個數字呈現出平均負載在幾何級減弱,依次表示持續1分鐘,5分鐘和15分鐘內。這三個數字能告訴咱們負載在時間線上是如何變化的。舉例說明,若是你在一個問題服務器上執行檢查,1分鐘的值遠遠低於15分鐘的值,能夠判斷出你也許登陸得太晚了,已經錯過了問題。
在上面的例子中,平均負載的數值顯示最近正在上升,1分鐘值高達30,對比15分鐘值則是19。這些指標值像如今這麼大意味着不少狀況:也許是CPU繁忙;vmstat 或者 mpstat 將能夠確認,本系列的第三和第四條命令。
$ 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-r ss:0kB [2320864.954447] TCP: Possible SYN flooding on port 7001. Dropping request. Check SNMP cou nters.
這個結果輸出了最近10條系統信息。能夠查看到引發性能問題的錯誤。上面的例子包含了oom-killer,以及TCP丟包。
譯者注:除了error級的日誌,info級的也要留個心眼,可能包含一些隱藏信息。
$ 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 是一個得到虛擬內存狀態概況的通用工具(最先建立於10年前的BSD)。它每一行記錄了關鍵的服務器統計信息。vmstat 運行的時候有一個參數1,用於輸出一秒鐘的概要數據。第一行輸出顯示啓動以後的平均值,用以替代以前的一秒鐘數據。如今,跳過第一行,讓咱們來學習而且記住每一列表明的意義。
r:正在CPU上運行或等待運行的進程數。相對於平均負載來講,這提供了一個更好的、用於查明CPU飽和度的指標,它不包括I/O負載。注: 「r」值大於CPU數便是飽和。
free: 空閒內存(kb)
若是這個數值很大,代表你還有足夠的內存空閒。包括命令7「free m」,很好地展示了空閒內存的狀態。
si, so: swap入/出。若是這個值非0,證實內存溢出了。
us, sy, id, wa, st:它們是CPU分類時間,針對全部CPU的平均訪問。分別是用戶時間,系統時間(內核),空閒,I/O等待時間,以及被偷走的時間(其它訪客,或者是Xen)。CPU分類時間將能夠幫助確認,CPU是否繁忙,經過累計用戶系統時間。等待I/O的情形確定指向的是磁盤瓶頸;這個時候CPU一般是空閒的,由於任務被阻塞以等待分配磁盤I/O。你能夠將等待I/O看成另外一種CPU空閒,一種它們爲何空閒的解釋線索。
系統時間對I/O處理很是必要。一個很高的平均系統時間,超過20%,值得深刻分析:也許是內核處理I/O很是低效。在上面的例子中,CPU時間幾乎徹底是用戶級的,與應用程序級的利用率正好相反。全部CPU的平均利用率也超過90%。這不必定是一個問題;還需檢查「r」列的飽和度。
$ 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 [...]
這個命令能夠按時間線打印每一個CPU的消耗,經常用於檢查不均衡的問題。若是隻有一個繁忙的CPU,能夠判斷是屬於單進程的應用程序。
$ 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 有一點像頂級視圖-針對每個進程,可是輸出的時候滾屏,而不是清屏。它很是有用,特別是跨時間段查看的模式,也能將你所看到的信息記錄下來,以利於進一步的研究。上面的例子識別出兩個 java 進程引發的CPU耗盡。「%CPU」 是對全部CPU的消耗;1591% 顯示 java 進程佔用了幾乎16個CPU。
$ 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 [...]
這是一個理解塊設備(磁盤)極好的工具,不管是負載評估仍是做爲性能測試成績。
r/s, w/s, rkB/s, wkB/s: 這些是該設備每秒讀%、寫%、讀Kb、寫Kb。可用於描述工做負荷。一個性能問題可能只是簡單地因爲一個過量的負載引發。
await: I/O平均時間(毫秒)
這是應用程序須要的時間,它包括排隊以及運行的時間。
遠遠大於預期的平均時間能夠做爲設備飽和,或者設備問題的指標。
avgqusz: 向設備發出的平均請求數。
值大於1可視爲飽和(儘管設備能對請求持續運行,特別是前端的虛擬設備-後端有多個磁盤)。
%util: 設備利用率
這是一個實時的繁忙的百分比,顯示設備每秒鐘正在進行的工做。值大於60%屬於典型的性能不足(能夠從await處查看),儘管它取決於設備。值接近100% 一般指示飽和。若是存儲設備是一個前端邏輯磁盤、後掛一堆磁盤,那麼100%的利用率也許意味着,一些已經處理的I/O此時佔用100%,然而,後端的磁盤也許遠遠沒有達到飽和,其實能夠承擔更多的工做。
切記:磁盤I/O性能低並不必定是應用程序問題。許多技術一向使用異步I/O,因此應用程序並不會阻塞,以及遭受直接的延遲(例如提早加載,緩衝寫入)。
$ free -m total used free shared buffers cached Mem: 245998 24545 221453 83 59 541 -/+ buffers/cache: 23944 222053 Swap: 0 0 0
buffers: buffer cache,用於塊設備I/O。
cached:page cache, 用於文件系統。
 
咱們只是想檢查這些指標值不爲0——那樣意味着磁盤I/O高、性能差(確認須要用iostat)。上面的例子看起來不錯,每一類內存都有富餘。
「/+ buffers/cache」: 提供了關於內存利用率更加準確的數值。
Linux能夠將空閒內存用於緩存,而且在應用程序須要的時候收回。因此應用到緩存的內存必須以另外一種方式包括在內存空閒的數據裏面。有一個網站linux ate my ram,專門探討這個困惑。它還有更使人困惑的地方,若是在Linux上使用ZFS,正如咱們運行一些服務,ZFS擁有本身的文件系統緩存,也不能在free -m 的輸出里正確反映。這種狀況會顯示系統空閒內存不足,可是內存實際上可用,經過回收 ZFS 的緩存。
關於 Linux 內存管理的更多內容,能夠閱讀操做系統原理:How Linux Works (Memroy)。
$ 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
使用這個工具用來檢查網絡接口吞吐量:rxkB/s 和 txkB/s, 做爲負載的一種度量方式, 也能夠用來檢查是否已經達到某種瓶頸。
在上面的例子中,網卡 eth0 收包大道 22 Mbytes/s, 即176 Mbits/sec (就是說,在 1 Gbit/sec 的限制以內)。此版本也有一個體現設備利用率的 「%ifutil」 (兩個方向最大值),咱們也可使用 Brendan的nicstat 工具來度量。和 nicstat 相似,這個值很難準確獲取,看起來在這個例子中並無起做用(0.00)。
$ 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
這是一個關鍵TCP指標的概覽視圖。包括:
active/s: 本地初始化的 TCP 鏈接數 /每秒(例如,經過connect() )
passive/s: 遠程初始化的 TCP 鏈接數/每秒(例如,經過accept() )
retrans/s: TCP重發數/每秒
這些活躍和被動的計數器經常做爲一種粗略的服務負載度量方式:新收到的鏈接數 (被動的),以及下行流量的鏈接數 (活躍的)。這也許能幫助咱們理解,活躍的都是外向的,被動的都是內向的,可是嚴格來講這種說法是不許確的(例如,考慮到「本地-本地」的鏈接)。重發數是網絡或服務器問題的一個標誌;它也許是由於不可靠的網絡(如,公共互聯網),也許是因爲一臺服務器已經超負荷、發生丟包。
上面的例子顯示每秒鐘僅有一個新的TCP鏈接。
$ 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命令包含了許多咱們以前已經檢查的指標。它能夠很是方便地運行,看看是否任何東西看起來與從前面的命令的結果徹底不一樣,能夠代表負載指標是不斷變化的。頂部下面的輸出,很難按照時間推移的模式查看,可能使用如 vmstat 和 pidstat 等工具會更清晰,它們提供滾動輸出。若是你保持輸出的動做不夠快 (CtrlS 要暫停,CtrlQ 繼續),屏幕將清除,間歇性問題的證據也會丟失。
故障檢查過程當中,人的做用主要是做出決策。遺忘、遺漏、麻痹、鬆懈是每一個人都會犯的錯誤,好的公司都會根據經驗編制檢查單,提升工做效率,下降人爲失誤發生的機率。出於競爭因素考慮,應該充分重視檢查單的更新、完善、自動化,以此爲基礎創建本身的技術壁壘。
發表在GitBook平臺,歡迎訂閱、下載、批評指正: https://www.gitbook.com/book/riboseyim/linux-perf-master/details