1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        系統(tǒng)的軟中斷CPU使用率升高,我該怎么辦?

        共 11874字,需瀏覽 24分鐘

         ·

        2021-08-23 16:41

        點(diǎn)擊上方“程序員大白”,選擇“星標(biāo)”公眾號(hào)

        重磅干貨,第一時(shí)間送達(dá)

        中斷是一種異步的事件處理機(jī)制,用來(lái)提高系統(tǒng)的并發(fā)處理能力。中斷事件發(fā)生,會(huì)觸發(fā)執(zhí)行中斷處理程序,而中斷處理程序被分為上半部和下半部這兩個(gè)部分。

        • 上半部對(duì)應(yīng)硬中斷,用來(lái)快速處理中斷;
        • 下半部對(duì)應(yīng)軟中斷,用來(lái)異步處理上半部未完成的工作。

        Linux 中的軟中斷包括網(wǎng)絡(luò)收發(fā)、定時(shí)、調(diào)度、RCU 鎖等各種類型,我們可以查看 proc 文件系統(tǒng)中的 /proc/softirqs  ,觀察軟中斷的運(yùn)行情況。

        在 Linux 中,每個(gè) CPU 都對(duì)應(yīng)一個(gè)軟中斷內(nèi)核線程,名字是 ksoftirqd/CPU 編號(hào)。當(dāng)軟中斷事件的頻率過(guò)高時(shí),內(nèi)核線程也會(huì)因?yàn)?CPU 使用率過(guò)高而導(dǎo)致軟中斷處理不及時(shí),進(jìn)而引發(fā)網(wǎng)絡(luò)收發(fā)延遲、調(diào)度緩慢等性能問(wèn)題。

        軟中斷 CPU 使用率過(guò)高也是一種最常見(jiàn)的性能問(wèn)題。今天,我就用最常見(jiàn)的反向代理服務(wù)器 Nginx 的案例,教你學(xué)會(huì)分析這種情況。

        案例

        接下來(lái)的案例基于 Ubuntu 18.04,也同樣適用于其他的 Linux 系統(tǒng)。我使用的案例環(huán)境是這樣的:

        • 機(jī)器配置:2 CPU、8 GB 內(nèi)存。
        • 預(yù)先安裝 docker、sysstat、sar 、hping3、tcpdump 等工具,比如 apt-get install docker.io sysstat hping3 tcpdump。

        這里我又用到了三個(gè)新工具,sar、  hping3 和 tcpdump,先簡(jiǎn)單介紹一下:

        • sar 是一個(gè)系統(tǒng)活動(dòng)報(bào)告工具,既可以實(shí)時(shí)查看系統(tǒng)的當(dāng)前活動(dòng),又可以配置保存和報(bào)告歷史統(tǒng)計(jì)數(shù)據(jù)。
        • hping3 是一個(gè)可以構(gòu)造 TCP/IP 協(xié)議數(shù)據(jù)包的工具,可以對(duì)系統(tǒng)進(jìn)行安全審計(jì)、防火墻測(cè)試等。
        • tcpdump 是一個(gè)常用的網(wǎng)絡(luò)抓包工具,常用來(lái)分析各種網(wǎng)絡(luò)問(wèn)題。

        本次案例用到兩臺(tái)虛擬機(jī),我畫了一張圖來(lái)表示它們的關(guān)系。

        你可以看到,其中一臺(tái)虛擬機(jī)運(yùn)行 Nginx ,用來(lái)模擬待分析的 Web 服務(wù)器;而另一臺(tái)當(dāng)作 Web 服務(wù)器的客戶端,用來(lái)給 Nginx 增加壓力請(qǐng)求。使用兩臺(tái)虛擬機(jī)的目的,是為了相互隔離,避免“交叉感染”。

        接下來(lái),我們打開(kāi)兩個(gè)終端,分別 SSH 登錄到兩臺(tái)機(jī)器上,并安裝上面提到的這些工具。

        同以前的案例一樣,下面的所有命令都默認(rèn)以 root 用戶運(yùn)行,如果你是用普通用戶身份登陸系統(tǒng),請(qǐng)運(yùn)行 sudo su root 命令切換到 root 用戶。

        操作和分析

        安裝完成后,我們先在第一個(gè)終端,執(zhí)行下面的命令運(yùn)行案例,也就是一個(gè)最基本的 Nginx 應(yīng)用:

        # 運(yùn)行Nginx服務(wù)并對(duì)外開(kāi)放80端口
        $ docker run -itd --name=nginx -p 80:80 nginx

        然后,在第二個(gè)終端,使用 curl 訪問(wèn) Nginx 監(jiān)聽(tīng)的端口,確認(rèn) Nginx 正常啟動(dòng)。假設(shè) 192.168.58.99 是 Nginx 所在虛擬機(jī)的 IP 地址,運(yùn)行 curl 命令后你應(yīng)該會(huì)看到下面這個(gè)輸出界面:

        $ curl http://192.168.58.99/
        <!DOCTYPE html>
        <html>
        <head>
        <title>Welcome to nginx!</title>
        ...

        接著,還是在第二個(gè)終端,我們運(yùn)行 hping3 命令,來(lái)模擬 Nginx 的客戶端請(qǐng)求:

        # -S參數(shù)表示設(shè)置TCP協(xié)議的SYN(同步序列號(hào)),-p表示目的端口為80
        # -i u100表示每隔100微秒發(fā)送一個(gè)網(wǎng)絡(luò)幀
        # 注:如果你在實(shí)踐過(guò)程中現(xiàn)象不明顯,可以嘗試把100調(diào)小,比如調(diào)成10甚至1
        $ hping3 -S -p 80 -i u100 192.168.58.99

        現(xiàn)在我們?cè)倩氐降谝粋€(gè)終端,你應(yīng)該發(fā)現(xiàn)了異常。是不是感覺(jué)系統(tǒng)響應(yīng)明顯變慢了,即便只是在終端中敲幾個(gè)回車,都得很久才能得到響應(yīng)?這個(gè)時(shí)候應(yīng)該怎么辦呢?

        雖然在運(yùn)行 hping3 命令時(shí),我就已經(jīng)告訴你,這是一個(gè) SYN FLOOD 攻擊,你肯定也會(huì)想到從網(wǎng)絡(luò)方面入手,來(lái)分析這個(gè)問(wèn)題。不過(guò),在實(shí)際的生產(chǎn)環(huán)境中,沒(méi)人直接告訴你原因。

        所以,我希望你把 hping3 模擬 SYN FLOOD 這個(gè)操作暫時(shí)忘掉,然后重新從觀察到的問(wèn)題開(kāi)始,分析系統(tǒng)的資源使用情況,逐步找出問(wèn)題的根源。

        那么,該從什么地方入手呢?剛才我們發(fā)現(xiàn),簡(jiǎn)單的 SHELL 命令都明顯變慢了,先看看系統(tǒng)的整體資源使用情況應(yīng)該是個(gè)不錯(cuò)的注意,比如執(zhí)行下 top 看看是不是出現(xiàn)了 CPU 的瓶頸。我們?cè)诘谝粋€(gè)終端運(yùn)行 top 命令,看一下系統(tǒng)整體的資源使用情況。

        # top運(yùn)行后按數(shù)字1切換到顯示所有CPU
        $ top
        top - 10:50:58 up 1 days, 22:10,  1 user,  load average: 0.00, 0.00, 0.00
        Tasks: 122 total,   1 running,  71 sleeping,   0 stopped,   0 zombie
        %Cpu0  :  0.0 us,  0.0 sy,  0.0 ni, 96.7 id,  0.0 wa,  0.0 hi,  3.3 si,  0.0 st
        %Cpu1  :  0.0 us,  0.0 sy,  0.0 ni, 95.6 id,  0.0 wa,  0.0 hi,  4.4 si,  0.0 st
        ...

          PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
            7 root      20   0       0      0      0 S   0.3  0.0   0:01.64 ksoftirqd/0
           16 root      20   0       0      0      0 S   0.3  0.0   0:01.97 ksoftirqd/1
         2663 root      20   0  923480  28292  13996 S   0.3  0.3   4:58.66 docker-containe
         3699 root      20   0       0      0      0 I   0.3  0.0   0:00.13 kworker/u4:0
         3708 root      20   0   44572   4176   3512 R   0.3  0.1   0:00.07 top
            1 root      20   0  225384   9136   6724 S   0.0  0.1   0:23.25 systemd
            2 root      20   0       0      0      0 S   0.0  0.0   0:00.03 kthreadd
        ...

        這里你有沒(méi)有發(fā)現(xiàn)異常的現(xiàn)象?我們從第一行開(kāi)始,逐個(gè)看一下:

        • 平均負(fù)載全是 0,就緒隊(duì)列里面只有一個(gè)進(jìn)程(1 running)。
        • 每個(gè) CPU 的使用率都挺低,最高的 CPU1 的使用率也只有 4.4%,并不算高。
        • 再看進(jìn)程列表,CPU 使用率最高的進(jìn)程也只有 0.3%,還是不高呀。

        那為什么系統(tǒng)的響應(yīng)變慢了呢?既然每個(gè)指標(biāo)的數(shù)值都不大,那我們就再來(lái)看看,這些指標(biāo)對(duì)應(yīng)的更具體的含義。畢竟,哪怕是同一個(gè)指標(biāo),用在系統(tǒng)的不同部位和場(chǎng)景上,都有可能對(duì)應(yīng)著不同的性能問(wèn)題。

        仔細(xì)看 top 的輸出,兩個(gè) CPU 的使用率雖然分別只有 3.3% 和 4.4%,但都用在了軟中斷上;而從進(jìn)程列表上也可以看到,CPU 使用率最高的也是軟中斷進(jìn)程 ksoftirqd??雌饋?lái),軟中斷有點(diǎn)可疑了。

        根據(jù)上一期的內(nèi)容,既然軟中斷可能有問(wèn)題,那你先要知道,究竟是哪類軟中斷的問(wèn)題。停下來(lái)想想,上一節(jié)我們用了什么方法,來(lái)判斷軟中斷類型呢?沒(méi)錯(cuò),還是 proc 文件系統(tǒng)。觀察 /proc/softirqs 文件的內(nèi)容,你就能知道各種軟中斷類型的次數(shù)。

        不過(guò),這里的各類軟中斷次數(shù),又是什么時(shí)間段里的次數(shù)呢?它是系統(tǒng)運(yùn)行以來(lái)的累積中斷次數(shù)。所以我們直接查看文件內(nèi)容,得到的只是累積中斷次數(shù),對(duì)這里的問(wèn)題并沒(méi)有直接參考意義。因?yàn)?,這些中斷次數(shù)的變化速率才是我們需要關(guān)注的。

        那什么工具可以觀察命令輸出的變化情況呢?我想你應(yīng)該想起來(lái)了,在前面案例中用過(guò)的  watch 命令,就可以定期運(yùn)行一個(gè)命令來(lái)查看輸出;如果再加上 -d 參數(shù),還可以高亮出變化的部分,從高亮部分我們就可以直觀看出,哪些內(nèi)容變化得更快。

        比如,還是在第一個(gè)終端,我們運(yùn)行下面的命令:

        $ watch -d cat /proc/softirqs
                            CPU0       CPU1
                  HI:          0          0
               TIMER:    1083906    2368646
              NET_TX:         53          9
              NET_RX:    1550643    1916776
               BLOCK:          0          0
            IRQ_POLL:          0          0
             TASKLET:     333637       3930
               SCHED:     963675    2293171
             HRTIMER:          0          0
                 RCU:    1542111    1590625

        通過(guò) /proc/softirqs 文件內(nèi)容的變化情況,你可以發(fā)現(xiàn), TIMER(定時(shí)中斷)、NET_RX(網(wǎng)絡(luò)接收)、SCHED(內(nèi)核調(diào)度)、RCU(RCU 鎖)等這幾個(gè)軟中斷都在不停變化。

        其中,NET_RX,也就是網(wǎng)絡(luò)數(shù)據(jù)包接收軟中斷的變化速率最快。而其他幾種類型的軟中斷,是保證 Linux 調(diào)度、時(shí)鐘和臨界區(qū)保護(hù)這些正常工作所必需的,所以它們有一定的變化倒是正常的。

        那么接下來(lái),我們就從網(wǎng)絡(luò)接收的軟中斷著手,繼續(xù)分析。既然是網(wǎng)絡(luò)接收的軟中斷,第一步應(yīng)該就是觀察系統(tǒng)的網(wǎng)絡(luò)接收情況。這里你可能想起了很多網(wǎng)絡(luò)工具,不過(guò),我推薦今天的主人公工具  sar  。

        sar 可以用來(lái)查看系統(tǒng)的網(wǎng)絡(luò)收發(fā)情況,還有一個(gè)好處是,不僅可以觀察網(wǎng)絡(luò)收發(fā)的吞吐量(BPS,每秒收發(fā)的字節(jié)數(shù)),還可以觀察網(wǎng)絡(luò)收發(fā)的 PPS,即每秒收發(fā)的網(wǎng)絡(luò)幀數(shù)。

        我們?cè)诘谝粋€(gè)終端中運(yùn)行 sar 命令,并添加 -n DEV 參數(shù)顯示網(wǎng)絡(luò)收發(fā)的報(bào)告:

        # -n DEV 表示顯示網(wǎng)絡(luò)收發(fā)的報(bào)告,間隔1秒輸出一組數(shù)據(jù)
        $ sar -n DEV 1
        15:03:46        IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s   %ifutil
        15:03:47         eth0  12607.00   6304.00    664.86    358.11      0.00      0.00      0.00      0.01
        15:03:47      docker0   6302.00  12604.00    270.79    664.66      0.00      0.00      0.00      0.00
        15:03:47           lo      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
        15:03:47    veth9f6bbcd   6302.00  12604.00    356.95    664.66      0.00      0.00      0.00      0.05

        對(duì)于 sar 的輸出界面,我先來(lái)簡(jiǎn)單介紹一下,從左往右依次是:

        • 第一列:表示報(bào)告的時(shí)間。
        • 第二列:IFACE 表示網(wǎng)卡。
        • 第三、四列:rxpck/s 和 txpck/s 分別表示每秒接收、發(fā)送的網(wǎng)絡(luò)幀數(shù),也就是 PPS。
        • 第五、六列:rxkB/s 和 txkB/s 分別表示每秒接收、發(fā)送的千字節(jié)數(shù),也就是 BPS。
        • 后面的其他參數(shù)基本接近 0,顯然跟今天的問(wèn)題沒(méi)有直接關(guān)系,你可以先忽略掉。

        我們具體來(lái)看輸出的內(nèi)容,你可以發(fā)現(xiàn):

        • 對(duì)網(wǎng)卡 eth0 來(lái)說(shuō),每秒接收的網(wǎng)絡(luò)幀數(shù)比較大,達(dá)到了 12607,而發(fā)送的網(wǎng)絡(luò)幀數(shù)則比較小,只有 6304;每秒接收的千字節(jié)數(shù)只有 664 KB,而發(fā)送的千字節(jié)數(shù)更小,只有 358 KB。
        • docker0 和 veth9f6bbcd 的數(shù)據(jù)跟 eth0 基本一致,只是發(fā)送和接收相反,發(fā)送的數(shù)據(jù)較大而接收的數(shù)據(jù)較小。這是 Linux 內(nèi)部網(wǎng)橋轉(zhuǎn)發(fā)導(dǎo)致的,你暫且不用深究,只要知道這是系統(tǒng)把 eth0 收到的包轉(zhuǎn)發(fā)給 Nginx 服務(wù)即可。具體工作原理,我會(huì)在后面的網(wǎng)絡(luò)部分詳細(xì)介紹。

        從這些數(shù)據(jù),你有沒(méi)有發(fā)現(xiàn)什么異常的地方?

        既然懷疑是網(wǎng)絡(luò)接收中斷的問(wèn)題,我們還是重點(diǎn)來(lái)看 eth0 :接收的 PPS 比較大,達(dá)到 12607,而接收的 BPS 卻很小,只有 664 KB。直觀來(lái)看網(wǎng)絡(luò)幀應(yīng)該都是比較小的,我們稍微計(jì)算一下,664*1024/12607 = 54 字節(jié),說(shuō)明平均每個(gè)網(wǎng)絡(luò)幀只有 54 字節(jié),這顯然是很小的網(wǎng)絡(luò)幀,也就是我們通常所說(shuō)的小包問(wèn)題。

        那么,有沒(méi)有辦法知道這是一個(gè)什么樣的網(wǎng)絡(luò)幀,以及從哪里發(fā)過(guò)來(lái)的呢?

        使用 tcpdump 抓取 eth0 上的包就可以了。我們事先已經(jīng)知道, Nginx 監(jiān)聽(tīng)在 80 端口,它所提供的 HTTP 服務(wù)是基于 TCP 協(xié)議的,所以我們可以指定 TCP 協(xié)議和 80 端口精確抓包。

        接下來(lái),我們?cè)诘谝粋€(gè)終端中運(yùn)行 tcpdump 命令,通過(guò) -i eth0 選項(xiàng)指定網(wǎng)卡 eth0,并通過(guò) tcp port 80 選項(xiàng)指定 TCP 協(xié)議的 80 端口:

        # -i eth0 只抓取eth0網(wǎng)卡,-n不解析協(xié)議名和主機(jī)名
        # tcp port 80表示只抓取tcp協(xié)議并且端口號(hào)為80的網(wǎng)絡(luò)幀
        $ tcpdump -i eth0 -n tcp port 80
        15:11:32.678966 IP 192.168.0.2.18238 > 192.168.0.30.80: Flags [S], seq 458303614, win 512, length 0
        ...

        從 tcpdump 的輸出中,你可以發(fā)現(xiàn)

        • 192.168.0.2.18238 > 192.168.0.30.80 ,表示網(wǎng)絡(luò)幀從 192.168.0.2 的 18238 端口發(fā)送到 192.168.0.30 的 80 端口,也就是從運(yùn)行 hping3 機(jī)器的 18238 端口發(fā)送網(wǎng)絡(luò)幀,目的為 Nginx 所在機(jī)器的 80 端口。
        • Flags [S] 則表示這是一個(gè) SYN 包。

        再加上前面用 sar 發(fā)現(xiàn)的, PPS 超過(guò) 12000 的現(xiàn)象,現(xiàn)在我們可以確認(rèn),這就是從 192.168.0.2 這個(gè)地址發(fā)送過(guò)來(lái)的 SYN FLOOD 攻擊。

        到這里,我們已經(jīng)做了全套的性能診斷和分析。從系統(tǒng)的軟中斷使用率高這個(gè)現(xiàn)象出發(fā),通過(guò)觀察 /proc/softirqs 文件的變化情況,判斷出軟中斷類型是網(wǎng)絡(luò)接收中斷;再通過(guò) sar 和 tcpdump ,確認(rèn)這是一個(gè) SYN FLOOD 問(wèn)題。

        SYN FLOOD 問(wèn)題最簡(jiǎn)單的解決方法,就是從交換機(jī)或者硬件防火墻中封掉來(lái)源 IP,這樣 SYN FLOOD 網(wǎng)絡(luò)幀就不會(huì)發(fā)送到服務(wù)器中。

        案例結(jié)束后,也不要忘了收尾,記得停止最開(kāi)始啟動(dòng)的 Nginx 服務(wù)以及 hping3 命令。

        在第一個(gè)終端中,運(yùn)行下面的命令就可以停止 Nginx 了:

        # 停止 Nginx 服務(wù)$ docker rm -f nginx

        小結(jié)

        軟中斷 CPU 使用率(softirq)升高是一種很常見(jiàn)的性能問(wèn)題。雖然軟中斷的類型很多,但實(shí)際生產(chǎn)中,我們遇到的性能瓶頸大多是網(wǎng)絡(luò)收發(fā)類型的軟中斷,特別是網(wǎng)絡(luò)接收的軟中斷。

        在碰到這類問(wèn)題時(shí),你可以借用 sar、tcpdump 等工具,做進(jìn)一步分析。

        有同學(xué)說(shuō)在查看軟中斷數(shù)據(jù)時(shí)會(huì)顯示128個(gè)核的數(shù)據(jù),我的也是,雖然只有一個(gè)核,但是會(huì)顯示128個(gè)核的信息,用下面的命令可以提取有數(shù)據(jù)的核,我的1核,所以這個(gè)命令只能顯示1核,多核需要做下修改

        watch -d "/bin/cat /proc/softirqs | /usr/bin/awk 'NR == 1{printf "%13s %s\\n"," ",$1}; NR > 1{printf "%13s %s\\n",$1,$2}'"
        (感謝閱讀,希望對(duì)你所有幫助)
        來(lái)源:www.jianshu.com/p/60f29e51ac27


        “拍一拍” 能撤回了 !??!

        5款Chrome插件,第1款絕對(duì)良心!

        為開(kāi)發(fā)色情游戲,這家公司赴日尋找AV女優(yōu)拍攝,期望暴力賺錢結(jié)果...

        拼多多終于釀成慘劇

        華為阿里下班時(shí)間曝光:所有的光鮮,都有加班的味道


        關(guān)


        ,學(xué)西學(xué)學(xué)運(yùn)營(yíng)護(hù)號(hào),樂(lè)質(zhì),結(jié)識(shí),關(guān)[],學(xué)習(xí)進(jìn)!


        瀏覽 92
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            精品一区在线 | 官场少妇伺候局长舒服了 | 国产性大片| 美国美女艳妇性bbw | 日韩成人AV电影在线观看 | 91精品国产刺激国语对白 | 3级片在线 | 懂色VA | 日本夫妇温泉の交换在线观看 | 亚洲AV小电影 |