Linux性能優化實戰學習筆記:第七講

1、進程的狀態

一、命令查看

top
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
28961 root      20   0   43816   3148   4040 R   3.2  0.0   0:00.01 top
  620 root      20   0   37280  33676    908 D   0.3  0.4   0:00.01 app
    1 root      20   0  160072   9416   6752 S   0.0  0.1   0:37.64 systemd
 1896 root      20   0       0      0      0 Z   0.0  0.0   0:00.00 devapp
    2 root      20   0       0      0      0 S   0.0  0.0   0:00.10 kthreadd
    4 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 kworker/0:0H
    6 root       0 -20       0      0      0 I   0.0  0.0   0:00.00 mm_percpu_wq
    7 root      20   0       0      0      0 S   0.0  0.0   0:06.37 ksoftirqd/0

二、進程狀態圖解

向一個進程發送SIGSTOP 信號,它就會因響應這個信號變成暫停狀態(Stopped);再向它發送 SIGCONT 信號,進程又會恢復運行(若是進程是終端裏直接起動的,docker

則須要你用fg命令,回覆到前臺運行)

瀏覽器

而當你的用的調試器調試一個進程是,在使用斷點中斷進程後,進程就會變成跟蹤狀態,這其實也就是一種特殊的暫停狀態,只不過你能夠用調試器
來跟蹤並按需控制進程的運行bash


瞭解了這些,咱們再回到今天的主題,先看不可終端狀態,這實際上是爲了保證進程數據與硬件狀態一直,而且增加狀況下,不可終端狀態在很短期內會結束,服務器

因此短時的不可終端進程咱們通常可忽略微信


但若是系統或硬件發生了故障,進程可能會在不可中斷狀態保持好久,甚至致使系統中出現大量不可中斷進程,這時,你就得注意下,系統時不時出現了I/O 等性能問題。app

再看殭屍進程,這是多進程應用很容易碰到的問題,正常狀況下,當一個進程建立了子進程後,它應該經過系統調用 wait() 或者 waitpid() 等待子進程結束,回收子進程的資源;
而子進程在結束時,會向它的父進程發送SIGCHLD 信號,因此,父進程還能夠註冊 SIGCHLD信號的處理函數,異步回收資源

異步

若是父進程這麼作,或是子進程執行太快,父進程尚未來得及處理子進程狀態,子進程就已經提早退出,那這時的紫禁城就會變成殭屍進程,換句話說,父親應該一直對兒子負責,有始有終,若是不做爲或者跟不上、都會致使"問題少年"的出現函數


一般、殭屍進程持續的時間都比較短,在父進程回收它的資源後就會消亡;或者在父進程推出後,由init進程回收後也會消亡性能


一旦父進程沒有處理子進程的種植,還一直保持運行狀態,那麼子進程就會一直處於殭屍狀態,大量的殭屍進程會用盡PID進程號,
致使新進程不能建立,因此這種狀況必定要避免學習

2、案例分析

一、運行案例應用

docker run --privileged --name=app -itd feisky/app:iowait

二、ps命令確認案例應用已正常啓動

ps aux | grep /app
root      4009  0.0  0.0   4376  1008 pts/0    Ss+  05:51   0:00 /app
root      4287  0.6  0.4  37280 33660 pts/0    D+   05:54   0:00 /app
root      4288  0.6  0.4  37280 33668 pts/0    D+   05:54   0:00 /app

一、s 和 + 是什麼意思呢?

s 表示這個進程是一個會話的領導進程,而 + 表示前臺進程組

這裏又出現了兩個新概念,進程組和會話,他們用來管理一組相互關聯的進程,意思其實很好理解

二、什麼是進程組?

進程組表示一組相互關聯的進程,好比每一個子進程都是父進程所在組的成員;而會話是隻共享同一個控制終端的一個或多個進程組

三、什麼是會話?

好比,我麼經過SSH登陸服務器,就會打開一個控制終端(TTY),這個控制終端就對應一個會話,而我咱們在終端中運行的命令以及他們的子進程
就構成了一個個的進程組,其中,在後臺運行的命令,構成後臺進程組;在前臺運行的命令,就構成前臺進程組

三、top查看資源使用狀況

# 按下數字 1 切換到全部 CPU 的使用狀況,觀察一下子按 Ctrl+C 結束
$ top
top - 05:56:23 up 17 days, 16:45,  2 users,  load average: 2.00, 1.68, 1.39
Tasks: 247 total,   1 running,  79 sleeping,   0 stopped, 115 zombie
%Cpu0  :  0.0 us,  0.7 sy,  0.0 ni, 38.9 id, 60.5 wa,  0.0 hi,  0.0 si,  0.0 st
%Cpu1  :  0.0 us,  0.7 sy,  0.0 ni,  4.7 id, 94.6 wa,  0.0 hi,  0.0 si,  0.0 st
...

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 4340 root      20   0   44676   4048   3432 R   0.3  0.0   0:00.05 top
 4345 root      20   0   37280  33624    860 D   0.3  0.0   0:00.01 app
 4344 root      20   0   37280  33624    860 D   0.3  0.4   0:00.01 app
    1 root      20   0  160072   9416   6752 S   0.0  0.1   0:38.59 systemd
...

四、分析過程

從這裏你能看出什麼問題嗎?逐行觀察,別放過任何一個地方,忘了哪行參數意思的話,也要及時返回去複習

先看第一行平均負載,過去一、五、15分鐘內的平均負載依次減少,說明平均負載正在升高,而1分鐘內的平均負載已經達到了系統CPU的個數,說明系統可能已經有了性能瓶頸

Tasks 有1個正在運行的進程,但殭屍進程比較多,並且還在不停增長,說明有子進程在退出時沒有沒清理

CPU使用率:用戶CPU和系統CPU都不高,但iowait分別是60.5%和94.6%好像有點不正常

每一個進程的狀況:CPU使用率最高的進程只有0.3%,看起來並不高;可是有兩個進程處於D狀態,它們可能在等待I/O,但光憑這裏並不能肯定是它們致使了 iowait 升高

咱們把這四個問題在彙總一下,就能夠獲得很明確的兩點:

第一點:iowait過高了,致使系統的平均負載生該,甚至達到系統CPU的個數

第二點:殭屍進程在不斷增多,說明程序沒能正確清理子進程的資源

3、遇到的問題及小結

一、用top命令觀察,平均負載也不高,而後wa也很低,也沒有看到D狀態的進程

二、解決辦法

老師說多是案例裏I/O線程還不夠多,效果不明顯,等着老師修改案例從新發鏡像,再實驗。
在和老師屢次交流下,終於逼得老師發佈一個把本身機器跑死的鏡像,就能夠了,結果和老師的溫和了。

[root@luoahong ~]# docker run --privileged --name=app -itd feisky/app:iowait-new2
Unable to find image 'feisky/app:iowait-new2' locally
iowait-new2: Pulling from feisky/app
32802c0cfa4d: Already exists
da1315cffa03: Already exists
fa83472a3562: Already exists
f85999a86bef: Already exists
f69cb5280862: Pull complete
Digest: sha256:9fc8b013aff0bc2c1b1dc41a33989a8ddd4ed7da56f53f6559bbc76836041dc2
Status: Downloaded newer image for feisky/app:iowait-new2
00ed5564248127a98c467eb99f8b32d3dc3ebc5d7f47563d6617ccfd7348b10b
[root@luoahong ~]# ps aux | grep /app
root      11798  0.1  0.0   4368   380 pts/0    Ss+  09:54   0:00 /app
root      11851  0.0  0.8  70040 65776 pts/0    R+   09:55   0:00 /app
root      11852  0.0  0.8  70040 65776 pts/0    R+   09:55   0:00 /app
root      11854  0.0  0.0 112708   980 pts/0    S+   09:55   0:00 grep --color=auto /app

top截圖

 

執行這個鏡像,iowait打滿,直接把個人微信給擠掉了,瀏覽器都打不開了,不過結果是好的。

 三、小結

用我麼最熟悉的ps或者top,能夠直接查看進程的狀態,這些狀態包括運行(R)、空閒(I)、不可中斷睡眠(D)、可中斷睡眠(S)、殭屍(Z)以及暫停(T)等

其中,不可中斷狀態和殭屍狀態,是咱們今天學習的重點

不可中斷狀態:表示進程正在跟硬件交互,爲了保護進程數據和硬件的一致性,系統不容許其餘進程或中斷打斷這個進程。進程長時間處於不可中斷狀態,一般標識系統有I/O 性能問題

殭屍進程表示進程已經退出,但它的父進程尚未回收子進程佔用資源。短暫的殭屍狀態咱們一般沒必要理會,但進程長時間屬於殭屍狀態,

就應該注意了,可能有應用程序沒有正常處理子進程退出

相關文章
相關標籤/搜索