日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

前言

作為一名測試人員,難免需要維護(hù)業(yè)務(wù)線的測試環(huán)境。初時每當(dāng)研發(fā)通知某某機(jī)器又掛了、某某機(jī)器太卡了,筆者完全兩眼一抹黑,無從入手。而當(dāng)了解了 linux 基本性能,熟悉其基本指標(biāo)時,遇到問題往往心里有底,甚至得心應(yīng)手。送人玫瑰,手有余香,特此整理,與君共享。

性能指標(biāo)

CPU 使用率

提起性能指標(biāo),最容易想到的是CPU使用率。linux 作為一個多任務(wù)系統(tǒng),將每個 CPU 的時間劃分為很短的時間片,通過調(diào)度器輪流分配給各個任務(wù)使用,造成多任務(wù)同時運(yùn)行的錯覺。而根據(jù) CPU 上執(zhí)行任務(wù)的不同,又可以細(xì)分為用戶CPU、系統(tǒng)CPU、等待 I/O CPU、軟中斷CPU 和硬中斷CPU 等。

  • 用戶CPU使用率(us + ni),包括用戶態(tài)CPU使用率(user)和低優(yōu)先級用戶態(tài)CPU使用率(nice),表示 CPU 在用戶狀態(tài)運(yùn)行的時間百分比。用戶CPU使用率高,說明有應(yīng)用程序比較繁忙。
  • 系統(tǒng)CPU使用率(sy),表示 CPU 在內(nèi)核狀態(tài)運(yùn)行的時間百分比。系統(tǒng)CPU使用率高,說明內(nèi)核比較繁忙。
  • 等待 I/O 使用率(wa),也稱為 iowait,表示等待 I/O 的時間百分比。iowait 高,說明系統(tǒng)與硬件設(shè)備的 I/O 交互時間比較長。
  • 軟中斷(si)和硬中斷(hi)的 CPU使用率,分別表示內(nèi)核調(diào)用軟中斷處理程序、硬中斷處理程序的時間百分比。它們的使用率高,通常說明系統(tǒng)發(fā)生了大量的中斷。

CPU使用率如何計算

CPU使用率描述了非空閑時間占總 CPU 時間的百分比。用公式表示為:

 

 

可以通過以下命令查看各個 CPU 的數(shù)據(jù):

$ cat /proc/stat | grep ^cpu
# cpu us ni sys id wa hi si st guest gnice
cpu  42849699018 205001 4396958253 10689835442 115714471 51747 397324892 0 0 0
cpu0 1448897830 9918 260556249 620723421 17589437 11620 80282872 0 0 0
cpu1 1802849978 8539 182700339 444025341 2238152 1 5138950 0 0 0
cpu2 1846754519 9857 177641895 405553744 1799005 0 4945465 0 0 0
cpu3 1854741192 10151 175660372 399834166 1748613 0 4771745 0 0 0
...

這里輸出的是一個表格,第一列為 CPU 的編號,如cpu0,而第一行沒有 CPU 編號,表示所有 CPU 的累加。其他列表示不同任務(wù)下 CPU 的時間,每一列的順序可以通過man proc 命令查看。通過這些數(shù)據(jù)就可以計算出當(dāng)前機(jī)器的 CPU使用率。然而,得到的 CPU 使用率是開機(jī)以來的平均CPU使用率,一般不具有參考價值。性能工具一般會取間隔一段時間的兩次差值,計算這段時間內(nèi)的平均CPU使用率,即:

 

 

如何查看CPU使用率

top和 ps 是常用的性能分析工具。top 能夠顯示系統(tǒng)總體的CPU和內(nèi)存使用情況,以及各進(jìn)程的資源使用情況。ps 顯示各進(jìn)程的資源使用情況。例如,top 的輸出格式為:

$ top
top - 21:23:36 up 283 days, 10:41,  2 users,  load average: 21.96, 14.46, 13.76
Tasks: 2009 total,  10 running, 1994 sleeping,   0 stopped,   5 zombie
Cpu(s): 32.5%us,  7.6%sy,  0.0%ni, 58.3%id,  0.6%wa,  0.0%hi,  0.9%si,  0.0%st
Mem:  98979248k total, 95372168k used,  3607080k free,  1479704k buffers
Swap:        0k total,        0k used,        0k free, 59440700k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
13159 user      20   0 9103m 6.0g  13m S  168  6.4 156503:16 mongod
31963 root      20   0  929m 882m  672 R   52  0.9   0:01.61 supervisord
...

其中,第三行 CPU 就是該機(jī)器的 CPU使用率,top 默認(rèn)每 3 秒刷新一次。默認(rèn)情況下顯示的是所有 CPU 的平均值,如果想了解每個 CPU 的使用情況,只需按下數(shù)字 1 即可。例如:

Cpu0  : 17.0%us, 10.2%sy,  0.0%ni, 64.9%id,  2.3%wa,  0.0%hi,  5.6%si,  0.0%st
Cpu1  : 12.1%us,  5.5%sy,  0.0%ni, 82.1%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu2  : 24.5%us,  4.0%sy,  0.0%ni, 71.2%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
...

從上我們可以發(fā)現(xiàn),top 并沒有細(xì)分進(jìn)程的用戶態(tài)CPU 和內(nèi)核態(tài)CPU,如果想了解每個進(jìn)程的詳細(xì)情況,可以使用 pidstat 工具。例如:

$ pidstat 1 1
Linux 3.2.0-23-generic (cs)     06/24/2021     _x86_64_    (24 CPU)

09:32:41 PM       PID    %usr %system  %guest    %CPU   CPU  Command
09:32:42 PM      1522    0.88    0.88    0.00    1.77    20  beam.smp
...

分析

一般來說,每種類型的 CPU使用率高,都有不同導(dǎo)致的條件,下面列出了這幾種導(dǎo)致不同 CPU使用率高的情況以及著重排查點(diǎn):

  • 用戶 CPU 和 Nice CPU 高,說明用戶態(tài)進(jìn)程占用了較多的 CPU,所以應(yīng)該著重排查進(jìn)程的性能問題。
  • 系統(tǒng) CPU 高,說明內(nèi)核態(tài)占用了較多的 CPU,所以應(yīng)該著重排查內(nèi)核線程或者系統(tǒng)調(diào)用的性能問題。
  • I/O 等待 CPU 高,說明等待 I/O 的時間比較長,所以應(yīng)該著重排查系統(tǒng)存儲是不是出現(xiàn)了 I/O 問題。
  • 軟中斷和硬中斷高,說明軟中斷或硬中斷的處理程序占用了較多的 CPU,所以應(yīng)該著重排查內(nèi)核中的中斷服務(wù)程序。

平均負(fù)載

第二能想到的就是平均負(fù)載。很多人會認(rèn)為,平均負(fù)載不就是單位時間內(nèi)的 CPU使用率嗎?其實并非如此。下面我們來一起熟悉下什么是平均負(fù)載。

通俗地說,平均負(fù)載是指單位時間內(nèi)系統(tǒng)處于可運(yùn)行狀態(tài)和不可中斷狀態(tài)的平均進(jìn)程數(shù),即平均活躍進(jìn)程數(shù)。從定義我們可以解讀到其實跟 CPU使用率無直接關(guān)系。

linux 將進(jìn)程的狀態(tài)劃分為以下幾種:

R 是 Running 的縮寫,表示進(jìn)程正在運(yùn)行或者正在等待運(yùn)行。

D 是 Disk Sleep 的縮寫,為不可中斷睡眠狀態(tài),進(jìn)程正與硬件進(jìn)行交互,交互過程不允許被其他進(jìn)程打斷,以防止數(shù)據(jù)丟失。

Z 是 Zombie 的縮寫,表示僵尸進(jìn)程,進(jìn)程實際已經(jīng)結(jié)束,但是父進(jìn)程還沒回收其資源,就會出現(xiàn)該狀態(tài)。

S 是 Interruptible Sleep 的縮寫,稱為可中斷睡眠狀態(tài),表示進(jìn)程因等待某個事件而被系統(tǒng)掛起。

I 是 Idle 的縮寫,為空閑狀態(tài),用于不可中斷睡眠的內(nèi)核線程上。

T 是 Traced 的縮寫,表示進(jìn)程處于暫停狀態(tài)。

X 是 Dead 的縮寫,表示進(jìn)程已經(jīng)消亡。

如何查看

通常使用 uptime 或 top 命令查看。例如,uptime 的輸出格式為:

$ uptime
15:22:50 up 284 days,  4:40,  3 users,  load average: 10.06, 12.15, 12.33

輸出分別表示為當(dāng)前時間、系統(tǒng)運(yùn)行時間、正在登錄用戶數(shù)以及過去 1 分鐘,5 分鐘,15 分鐘的平均負(fù)載。輸出這三個時間的平均負(fù)載有什么含義呢?

  • 數(shù)值基本相同,說明系統(tǒng)負(fù)載趨于平穩(wěn)。
  • 數(shù)值從過去 15 分鐘到過去 1 分鐘逐漸升高,說明系統(tǒng)運(yùn)行任務(wù)在增多,需要我們?nèi)ビ^察和判斷這種升高是否合理。
  • 數(shù)值從過去 15 分鐘到過去 1 分鐘在逐漸降低,說明系統(tǒng)運(yùn)行任務(wù)在減少。

基于此就可以粗略判斷當(dāng)前的系統(tǒng)負(fù)載情況。上面的例子可以看到目前的系統(tǒng)負(fù)載下降的。

多少為合理

平均負(fù)載這一數(shù)據(jù)沒有針對 CPU 個數(shù)作歸一化處理,因此最理想情況是平均負(fù)載等于 CPU 的個數(shù)。在評判當(dāng)前系統(tǒng)是否過載時,首先需要知道當(dāng)前系統(tǒng)的 CPU 個數(shù),可以通過 top 或者 lscpu 查看。例如:

$ lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                24
...

當(dāng)知道了 CPU 個數(shù)后,就可以結(jié)合平均負(fù)載來判斷當(dāng)前系統(tǒng)的運(yùn)行情況了。一旦負(fù)載過高,會導(dǎo)致進(jìn)程響應(yīng)變慢,影響服務(wù)的正常功能。故當(dāng)出現(xiàn)負(fù)載有明顯升高趨勢時,就需要我們?nèi)シ治龊驼{(diào)查了。通常認(rèn)為平均負(fù)載低于 CPU 數(shù)量 70% 時為合理狀態(tài),但不是絕對的,還需要參考負(fù)載的變化趨勢來作判斷。

CPU上下文切換

前面描述了 linux 系統(tǒng)會在很短的時間內(nèi)把 CPU 輪流分配給任務(wù)(進(jìn)程),造成多個任務(wù)同時運(yùn)行的錯覺。而這些任務(wù)都是從哪里加載以及開始運(yùn)行的呢?這就引出了 CPU上下文。CPU寄存器和程序計數(shù)器被叫做 CPU 的上下文,那么,CPU寄存器和程序計數(shù)器分別有什么作用呢?

  • CPU寄存器,存放數(shù)據(jù)的小型存儲區(qū)域,用來暫時存放參與運(yùn)算的數(shù)據(jù)和運(yùn)算結(jié)果。
  • 程序計數(shù)器,用來存儲 CPU 下一條指令位置。

而 CPU上下文切換,就是把前一個任務(wù)的 CPU上下文保存起來,然后加載新任務(wù)的上下文到寄存器和程序計數(shù)器中,最后跳轉(zhuǎn)到程序計數(shù)器所指位置,執(zhí)行新任務(wù)。根據(jù)任務(wù)的不同,可以分為三種切換場景:進(jìn)程上下文切換、線程上下文切換以及中斷上下文切換。

進(jìn)程上下文切換

提到進(jìn)程上下文切換,就不得不提到系統(tǒng)調(diào)用。linux 按照特權(quán)等級,把進(jìn)程的運(yùn)行空間劃分為內(nèi)核空間和用戶空間。

  • 內(nèi)核空間,具有最高權(quán)限,可以訪問所有資源。
  • 用戶空間,訪問受限,不能直接訪問內(nèi)存等硬件設(shè)備,只能通過系統(tǒng)調(diào)用到內(nèi)核中,由內(nèi)核訪問。

系統(tǒng)調(diào)用和普通函數(shù)調(diào)用非常相似,只不過,系統(tǒng)調(diào)用由操作系統(tǒng)核心提供,運(yùn)行于內(nèi)核態(tài),而普通函數(shù)調(diào)用由函數(shù)庫或用戶提供,運(yùn)行于用戶態(tài)。比如,某一進(jìn)程需要查看文件內(nèi)容時,就需要系統(tǒng)調(diào)用來完成:首先調(diào)用 open() 打開文件,通過 read() 讀取文件內(nèi)容,并通過 write() 寫到到標(biāo)準(zhǔn)輸出,最后通過 close() 關(guān)閉文件。系統(tǒng)調(diào)用結(jié)束后,CPU寄存器恢復(fù)到原來保存的用戶態(tài),切換到用戶空間,繼續(xù)執(zhí)行進(jìn)程。

從上我們可以知道,系統(tǒng)調(diào)用是在進(jìn)程內(nèi)進(jìn)行的,其與進(jìn)程上下文切換有點(diǎn)不同,它不會涉及到虛擬內(nèi)存等用戶態(tài)資源。所以我們通常稱系統(tǒng)調(diào)用為一種特權(quán)模式切換,而在系統(tǒng)調(diào)用用上下文切換是不可避免的,一次系統(tǒng)調(diào)用發(fā)生了兩次上下文切換。

進(jìn)程是由內(nèi)核管理和調(diào)度的,進(jìn)程的上下文切換在內(nèi)核態(tài)進(jìn)行,故其上下文切換要比系統(tǒng)調(diào)用多了一步:在保存當(dāng)前進(jìn)程的內(nèi)核狀態(tài)和 CPU寄存器之前,需要先把該進(jìn)程的虛擬內(nèi)存、棧等用戶資源保存起來。

那么,什么時候需要進(jìn)行上下文切換呢?

  • 進(jìn)程的系統(tǒng)資源不足時,進(jìn)程就會被掛起,等到資源充足時才能進(jìn)行。
  • 進(jìn)程通過 sleep 睡眠函數(shù)等方法主動掛起時。
  • 當(dāng)有更高優(yōu)先級的進(jìn)程運(yùn)行時,例如中斷等,進(jìn)程會被掛起,來保證高優(yōu)先級進(jìn)程正常運(yùn)行。

線程上下文切換

我們知道,線程是調(diào)度的基本單位,而進(jìn)程是資源擁有的基本單位,即內(nèi)核中的任務(wù)調(diào)度實際對象是線程,進(jìn)程只是給線程提供了虛擬內(nèi)存等資源。如果進(jìn)程中有多個線程,則線程會共享虛擬內(nèi)存等資源。因此,對于線程上下文切換就有兩種情況:

  • 前后切換線程屬于同一進(jìn)程,則虛擬內(nèi)存等資源就不需要切換,只需要切換線程需要的私有資源。
  • 前后切換線程屬于兩個進(jìn)程,此時跟進(jìn)程上下文切換一致。

由此我們知道同一進(jìn)程的線程上下文切換,要比進(jìn)程間的上下文切換耗費(fèi)更少資源,這也是多線程代替多進(jìn)程的一大優(yōu)勢。

中斷上下文切換

中斷要比進(jìn)程的優(yōu)先級更高,其會打斷進(jìn)程的正常調(diào)度,因此中斷程序需要更短小精悍,以便盡可能快地結(jié)束。

中斷上下文切換與進(jìn)程不同,其不需要虛擬內(nèi)存、全局變量等用戶態(tài)資源,只需要如 CPU寄存器、硬件中斷參數(shù)等內(nèi)核態(tài)中斷服務(wù)程序所需要的狀態(tài)。

如何查看

查看系統(tǒng)總體的上下文切換情況可以通過 vmstat 命令,其輸出格式為:

$ vmstat 1 1
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
10  0      0 1653888 1477852 61630304    0    0     0   112    0    0 73  8 19  0

其中,需要關(guān)注以下幾個參數(shù):

  • r (running),正在運(yùn)行和等待運(yùn)行的進(jìn)程數(shù)。
  • b (blocked),不可中斷睡眠狀態(tài)的進(jìn)程數(shù)。
  • in (interrupt),每秒中斷次數(shù)。
  • cs (context switch), 每秒的上下文切換次數(shù)。

而如果我們想要查看進(jìn)程的上下文切換,可以通過 pidstat 查看,輸出格式為:

# 通過參數(shù) -w 可以查看進(jìn)程每秒的上下文切換次數(shù)
$ pidstat -w 1 1
Linux 3.2.0-23-generic (cs)     06/26/2021     _x86_64_    (24 CPU)

03:19:25 PM       PID   cswch/s nvcswch/s  Command
03:19:26 PM         1      0.85      0.00  init
03:19:26 PM         3      0.85      0.00  ksoftirqd/0
...

其中,需要關(guān)注兩個參數(shù):

  • cswch (voluntary context switch),每秒自愿上下文切換次數(shù)。當(dāng)進(jìn)程無法獲取資源,比如內(nèi)存、IO 等資源不足時,就會發(fā)生自愿上下文切換。
  • nvcswch (non voluntary context switch),每秒非自愿上下文切換次數(shù)。當(dāng)進(jìn)程的時間片已到,比如大量進(jìn)程爭搶 CPU 時,就會被系統(tǒng)強(qiáng)制調(diào)度,發(fā)生非自愿上下文切換。

如果我們想要查看線程間的上下文切換,還是可以通過 pidstat 查看,加上 -wt 參數(shù)選項,輸出格式為:

$ pidstat -wt 1 1
linux 3.2.0-23-generic (cs7)     06/26/2021      _x86_64_        (24 CPU)

03:34:07 PM      TGID       TID   cswch/s nvcswch/s  Command
03:34:07 PM      2200         -      0.64      0.00  flush-8:48
03:34:07 PM         -      2200      0.64      0.00  |__flush-8:48
03:34:07 PM         -      2524    136.54      0.00  |__influxd
03:34:07 PM         -      2537     26.92      0.00  |__influxd
03:34:07 PM         -      3701     12.82      3.21  |__1_scheduler
03:34:07 PM         -      3702      0.64      0.00  |__2_scheduler
03:34:07 PM         -      3725      1.28      0.00  |__aux
...

多少為合理

據(jù)統(tǒng)計,每次上下文切換需要耗費(fèi)幾十納秒到數(shù)微秒的CPU時間,這個時間還是可以接受的。但是過多的上下文切換,會把 CPU 時間都耗費(fèi)在寄存器、內(nèi)存棧以及虛擬內(nèi)存的保存和恢復(fù)上,縮短進(jìn)程真正運(yùn)行的時間,導(dǎo)致系統(tǒng)性能大幅下降。那么,我們肯定想了解,多少的 CPU上下文切換為合理情況呢?

這取決于 CPU 的性能。如果上下文切換穩(wěn)定,那么從數(shù)百到上萬都是合理的。但是當(dāng) CPU上下文切換呈數(shù)量級增大時,或者數(shù)值已超過上萬次且不斷增長時,就可能出現(xiàn)了性能問題,需要我們著重排查。

CPU緩存命中率

CPU緩存是為了協(xié)調(diào)CPU處理速度和內(nèi)存訪問速度之間的差距而出現(xiàn)的空間,可分為 L1、L2 和 L3 三級緩存。離 CPU 核心越近,緩存的讀寫速度就越快,因此三級緩存的讀寫速度快慢分別是:L1 > L2 > L3.

如果 CPU 所操作的數(shù)據(jù)在緩存中,則可以直接讀取,稱為緩存命中。命中緩存可以帶來很大的性能提升。因此,考慮 CPU 的緩存命中率對于 linux 性能也至關(guān)重要。

查看系統(tǒng)的內(nèi)存情況,可通過 top 或 free 命令。比如,free 命令輸出格式為:

$ free
             total       used       free     shared    buffers     cached
Mem:      98979248   97562252    1416996          0    1478000   62018692
Swap:            0          0          0

輸出分別是物理內(nèi)存 Mem 和交換分區(qū) Swap 的使用情況。其中,每一列分別是:

  • total ,總內(nèi)存大小。
  • used,已使用內(nèi)存的大小。
  • free,未使用的內(nèi)存大小。
  • shared,共享內(nèi)存的大小。
  • buffers/cached,緩存和緩沖區(qū)的大小

查看 buffers 和 cache 的變化情況,可通過 vmstat 命令,輸出格式:

$ vmstat 1 1
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 9  0      0 1571640 1478044 62034792    0    0     0   112    0    0 73  8 19  0
  • buffer 和 cache 就是上面所說的緩存和緩沖區(qū)的大小,單位為 KB。
  • bi 和 bo 分別表示塊設(shè)備讀取和寫入的大小,單位為塊 / 秒。linux 中塊的大小是 1KB,故單位等價于 KB/s。

實踐

下面就目前機(jī)器出現(xiàn)的系統(tǒng)使用率過高的情況進(jìn)行排查。

通過 top 可以查看當(dāng)前的系統(tǒng)性能情況:

$ top
top - 16:41:29 up 285 days,  5:59,  2 users,  load average: 9.82, 11.53, 12.92
Tasks: 2010 total,   9 running, 2000 sleeping,   0 stopped,   1 zombie
Cpu(s): 34.5%us,  6.5%sy,  0.0%ni, 57.6%id,  0.5%wa,  0.0%hi,  0.9%si,  0.0%st
Mem:  98979248k total, 97548032k used,  1431216k free,  1478084k buffers
Swap:        0k total,        0k used,        0k free, 62122812k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
13159 user      20   0 9128m 6.1g  13m S   90  6.5 160516:12 mongod
19638 root      20   0  929m 882m  520 R   58  0.9   0:01.81 supervisord
...

CPU用戶使用率為 34.5%,系統(tǒng)使用率為 6.5%,空閑時間占 57.6%,系統(tǒng)使用流暢。可以看出,當(dāng)前的系統(tǒng)是比較空閑的。

然后,我執(zhí)行某些操作。再通過 top 命令查看當(dāng)前的系統(tǒng)性能情況:

$ top
Tasks: 2020 total,  16 running, 2004 sleeping,   0 stopped,   0 zombie
Cpu(s): 64.5%us, 13.6%sy,  0.0%ni, 20.5%id,  0.2%wa,  0.0%hi,  1.1%si,  0.0%st
Mem:  98979248k total, 98003524k used,   975724k free,  1478128k buffers
Swap:        0k total,        0k used,        0k free, 62228740k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
13159 user      20   0 9128m 6.2g  13m S  249  6.5 160538:08 mongod
15108 root      20   0  929m 882m  620 R   73  0.9   0:02.24 supervisord
15121 root      20   0  929m 882m  620 R   66  0.9   0:02.03 supervisord
15122 root      20   0  929m 882m  620 R   66  0.9   0:02.03 supervisord
...

可以發(fā)現(xiàn),系統(tǒng)使用率已經(jīng)增至了原來的一倍。CPU使用率除了服務(wù) mongod 最高以外,有幾個 supervisord 啟動的服務(wù)也出現(xiàn)了CPU使用率增高的情況。通過 pidstat 命令分析這些進(jìn)程的系統(tǒng)資源占用情況:

$ pidstat -p 15108
Linux 3.2.0-23-generic (cs)     06/26/2021     _x86_64_    (24 CPU)

05:03:14 PM       PID    %usr %system  %guest    %CPU   CPU  Command

發(fā)現(xiàn)該進(jìn)程并沒有輸出任何的資源使用信息。是 pidstat 指令出故障了?可以通過 ps 指令來交叉確認(rèn)一下:

$ ps aux | grep 15108
2003     14211  0.0  0.0   8748   948 pts/2    S+   17:07   0:00 grep --color=auto 15108

確實沒有輸出。現(xiàn)在發(fā)現(xiàn)問題了,原來是進(jìn)程已經(jīng)不存在了,所以 pidstat 沒有任何輸出。繼續(xù)分析其他幾個高 CPU使用率的進(jìn)程,發(fā)現(xiàn)亦如此。既然進(jìn)程沒有了,那么性能問題應(yīng)該已經(jīng)沒有了吧。通過 top 命令確認(rèn)下:

$ top
Tasks: 2019 total,  18 running, 2001 sleeping,   0 stopped,   0 zombie
Cpu(s): 60.5%us, 13.4%sy,  0.0%ni, 24.7%id,  0.4%wa,  0.0%hi,  1.1%si,  0.0%st
Mem:  98979248k total, 98118260k used,   860988k free,  1478272k buffers
Swap:        0k total,        0k used,        0k free, 62353676k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
13159 user      20   0 9129m 6.2g  13m S  260  6.5 160559:54 mongod
27114 root      20   0  929m 882m  580 R   63  0.9   0:01.94 supervisord
27145 root      20   0  929m 882m  600 R   60  0.9   0:01.87 supervisord
...

好像問題依舊存在,系統(tǒng)CPU使用率依舊很高。仔細(xì)查看 top 的輸出,發(fā)現(xiàn) supervisord 進(jìn)程的 pid 每次都有變化,現(xiàn)在已經(jīng)變成了 27114。進(jìn)程的 PID 號在變化,說明了什么?有兩點(diǎn):

  • 進(jìn)程在不斷的重啟,比如因為段錯誤、配置錯誤等,進(jìn)程退出后可能又被監(jiān)控系統(tǒng)重啟了。
  • 這些進(jìn)程都是短時進(jìn)程。這些進(jìn)程一般只運(yùn)行很短時間結(jié)束,很難通過 top 發(fā)現(xiàn)。

supervisor 是一個進(jìn)程管理程序,能夠監(jiān)控進(jìn)程狀態(tài),異常退出時能自動重啟。目前看來,極有可能是第一種情況。通過 supervisor 來查看服務(wù)狀態(tài):

 

 

從 uptime 更新時間長短可以發(fā)現(xiàn),很多服務(wù)在不斷地重啟。可能是服務(wù)配置或者代碼問題引起的。其實是批量的服務(wù)出現(xiàn)配置問題導(dǎo)致了服務(wù)啟動失敗,然后 supervisor 監(jiān)控到服務(wù)沒有成功啟動后又自動重啟。在解決完這些服務(wù)問題后,通過 top 再次看看性能情況:

$ top
Tasks: 2012 total,   7 running, 2002 sleeping,   0 stopped,   3 zombie
Cpu(s): 29.7%us,  5.4%sy,  0.0%ni, 63.5%id,  0.8%wa,  0.0%hi,  0.5%si,  0.0%st
Mem:  98979248k total, 96231348k used,  2747900k free,  1470892k buffers
Swap:        0k total,        0k used,        0k free, 60741708k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
13159 user      20   0 9131m 6.2g  13m S   80  6.6 160593:01 mongod
27545 user      20   0 41880 6636 2896 S   61  0.0   0:01.86 Python/ target=_blank class=infotextkey>Python
27549 root      20   0  929m 882m  616 R   38  0.9   0:01.15 supervisord
...

總結(jié)

在動手進(jìn)行性能優(yōu)化前,需要考慮以下幾個問題:

  • 如何判斷優(yōu)化是有效的呢?
  • 有多個性能問題同時發(fā)生時,應(yīng)該先優(yōu)化哪一個?
  • 提升方法有多種時,應(yīng)該選擇哪一種?

對于第一個問題,我們解決性能問題的目的,自然有一個性能提升的效果,即要對性能指標(biāo)進(jìn)行量化,需要確認(rèn)優(yōu)化前指標(biāo)、優(yōu)化后指標(biāo)。當(dāng)優(yōu)化后指標(biāo)與優(yōu)化前指標(biāo)有不同時,才能判定我們的優(yōu)化有沒有效果。比如上述例子中的系統(tǒng)CPU使用率優(yōu)化前后的變化。

對于第二個問題,有一個 “二八原則”,也就是 80% 的問題都是由 20% 的代碼導(dǎo)致的。因此,并不是所有的性能問題都值得優(yōu)化。在動手優(yōu)化前,往往需要把所有性能問題分析一遍,找出最重要的、可以最大程度提升性能的問題。這個過程會花費(fèi)較多的時間,下面有兩個可以簡化這一過程的方法:

  • 如果發(fā)現(xiàn)出現(xiàn)系統(tǒng)瓶頸問題,那么首先優(yōu)化的一定是系統(tǒng)資源問題。
  • 針對不同類型的指標(biāo),首先要去優(yōu)化那些性能指標(biāo)變化幅度最大的問題。

對于第三個問題,一般來說,應(yīng)該選擇能最大程度提升性能的方法。但是需要注意的是,性能優(yōu)化并非沒有成本,很有可能你優(yōu)化了一個指標(biāo),另一個指標(biāo)的性能就變差了。

參考

  • https://time.geekbang.org/column/article/69618
  • https://time.geekbang.org/column/article/69859
  • https://time.geekbang.org/column/article/70476
  • https://time.geekbang.org/column/article/72147
  • http://www.lyyyuna.com/2020/05/29/perftest-analysis-cpu1/
  • https://juejin.cn/post/6844903608371118094
  • https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/top.html

分享到:
標(biāo)簽:性能 Linux
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運(yùn)動步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定