性能分析(5)- 軟中斷導致 CPU 使用率過高的案例


性能分析小案例系列,可以通過下面鏈接查看哦

https://www.cnblogs.com/poloyy/category/1814570.html

 

前言

軟中斷基本原理,可參考這篇博客:https://www.cnblogs.com/poloyy/p/13435519.html

 

中斷

  • 一種異步的事件處理機制,用來提供系統的並發處理能力
  • 當中斷事件發生,會觸發執行中斷處理程序
  • 中斷處理程序分為上半部和下半部
  • 上半部:硬中斷,快速處理中斷
  • 下半部:軟中斷,用來異步處理上半部未完成的工作 

 

軟中斷

  • 每個 CPU 都對應一個軟中斷內核線程,名字是 ksoftirqd/CPU 編號
  • 當軟中斷事件的頻率過高時,內核線程也會因為 CPU 使用率過高而導致軟中斷處理不及時,進而引發網絡收發延遲,調度緩慢等性能問題

                                  

軟中斷頻率過高案例

系統配置

Ubuntu 18.04, 2 CPU,2GB 內存,共兩台虛擬機

 

三個工具

  • sar:是一個系統活動報告工具,既可以實時查看系統的當前活動,又可以配置保存和報告 歷史統計數據。
  • hping3:是一個可以構造 TCP/IP 協議數據包的工具,可以對系統進行安全審計、防火牆 測試等。
  • tcpdump:是一個常用的網絡抓包工具,常用來分析各種網絡問題

 

虛擬機關系

 

通過 docker 運行案例

在 VM1 中執行命令

docker run -itd --name=nginx -p 80:80 nginx

 

通過 curl 確認 Nginx 正常啟動

在 VM2 中執行命令

curl http://172.20.72.58/

 

通過 hping3 模擬 Nginx 的客戶端請求

在 VM2 中執行命令

hping3 -S -p 80 -i u100 172.20.72.58
  • -S:參數表示設置 TCP 協議的 SYN(同步序列號)
  • -p:表示目的端口為 80
  • -i:u100 表示每隔 100 微秒發送一個網絡幀

 

回到 VM1

感覺系統響應明顯變慢了,即便只 是在終端中敲幾個回車,都得很久才能得到響應

 

分析系統為什么會響應變慢

以下命令均在 VM1 中執行

 

通過 top 命令查看系統資源使用情況

  1. 系統 CPU 使用率(用戶態 us 和內核態 sy )並不高 
  2. 平均負載適中,只有 2 個 R 狀態的進程,無僵屍進程
  3. 但是軟中斷進程1號(ksoftirqd/1)的 CPU 使用率偏高,而且處理軟中斷的 CPU 占比已達到 94
  4. 此外,並無其他異常進程
  5. 可以猜測,軟中斷就是罪魁禍首

 

確認是什么類型的軟中斷

觀察 /proc/softirqs 文件的內容,就能知道各種軟中斷類型的次數

 

這里的各類軟中斷次數,又是什么時間段里的次數呢?

  • 它是系統運行以來的累積中斷次數
  • 所以直接查看文件內容,得到的只是累積中斷次數,對這里的問題並沒有直接參考意義
  • 中斷次數的變化速率才是我們需要關注的

 

通過 watch 動態查看命令輸出結果

因為我的機器是兩核,如果直接讀取 /proc/softirqs 會打印 128 核的信息,但對於我來說,只要看前面兩核的信息足以,所以需要寫提取關鍵數據

watch -d "/bin/cat /proc/softirqs | /usr/bin/awk 'NR == 1{printf \"%-15s %-15s %-15s\n\",\" \",\$1,\$2}; NR > 1{printf \"%-15s %-15s %-15s\n\",\$1,\$2,\$3}'"

結果分析

  • TIMER(定時中斷)、 NET_RX(網絡接收)、SCHED(內核調度)、RCU(RCU 鎖)等這幾個軟中斷都在不停變化
  • NET_RX,就是網絡數據包接收軟中斷變化速率最快
  • 其他幾種類型的軟中斷,是保證 Linux 調度、時鍾、臨界區保護這些正常工作所必需的,所以有變化時正常的

 

通過 sar 查看系統的網絡收發情況

上面確認了從網絡接收的軟中斷入手,所以第一步應該要看下系統的網絡接收情況

 

sar 的好處

  • 不僅可以觀察網絡收發的吞吐量(BPS,每秒收發的字節數)
  • 還可以觀察網絡收發的 PPS(每秒收發的網絡幀數)

 

執行 sar 命令

sar -n DEV 1

  • 第二列:IFACE 表示網卡
  • 第三、四列:rxpck/s 和 txpck/s 分別表示每秒接收、發送的網絡幀數【PPS】
  • 第五、六列:rxkB/s 和 txkB/s 分別表示每秒接收、發送的千字節數【BPS】

 

結果分析

對網卡 ens33 來說

  • 每秒接收的網絡幀數比較大,幾乎達到 8w,而發送的網絡幀數較小,只有接近 4w
  • 每秒接收的千字節數只有 4611 KB,發送的千字節數更小,只有2314 KB

 

docker0 veth04076e3

  • 數據跟 ens33 基本一致只是發送和接收相反,發送的數據較大而接收的數據較小
  • 這是 Linux 內部網橋轉發導致的,暫且不用深究,只要知道這是系統把 ens33 收到的包轉發給 Nginx 服務即可

 

異常點

  • 前面說到是網絡數據包接收軟中斷的問題,那就重點看 ens33
  • 接收的 PPS 達到 8w,但接收的 BPS 只有 5k 不到,網絡幀看起來是比較小的
  • 4611 * 1024 / 78694 = 64 字節,說明平均每個網絡幀只有 60 字節,這顯然是很小的網絡幀,也就是常說的小包問題

 

靈魂拷問

如何知道這是一個什么樣的網絡幀,它又是從哪里發過來的呢?

 

通過 tcpdump 抓取網絡包

已知條件

Nginx 監聽在 80 端口, 它所提供的 HTTP 服務是基於 TCP 協議的

 

執行 tcpdump 命令

tcpdump -i ens33 -n tcp port 80
  • -i ens33:只抓取 ens33 網卡
  • -n:不解析協議名和主機名
  • tcp port 80:表示只抓取 tcp 協議並且端口號為 80 的網絡幀

172.20.72.59.52195 > 172.20.72.58.80

  • 表示網絡幀從 172.20.72.59 的 52195 端口發 送到 172.20.72.58 的 80 端口
  • 也就是從運行 hping3 機器的 52195 端口發送網絡幀, 目的為 Nginx 所在機器的 80 端口

 

Flags [S]

表示這是一個 SYN 包

 

性能分析結果

結合 sar 命令發現的 PPS 接近 4w 的現象,可以認為這就是從 172.20.72.59 這個地址發送過來的 SYN FLOOD 攻擊

 

解決 SYN FLOOD 問題

從交換機或者硬件防火牆中封掉來源 IP,這樣 SYN FLOOD 網絡幀就不會發送到服務器中

 

后續的期待

至於 SYN FLOOD 的原理和更多解決思路在后面會講到哦

 

分析的整體思路

  1. 系統出現卡頓,執行命令,響應也會變慢
  2. 通過 top 查看系統資源情況
  3. 發現 CPU 使用率(us 和 sy)均不高,平均負載適中,沒有超 CPU 核數的運行狀態的進程,也沒有僵屍進程
  4. 但是發現處理軟中斷的 CPU 占比(si)較高,在進程列表也可以看到軟中斷進程 CPU 使用率偏高,猜測是軟中斷導致系統變卡頓的主要原因
  5. 通過 /proc/sorfirqs 查看軟中斷類型和變化頻率,發現直接 cat 的話會打印 128 個核的信息,但只想要兩個核的信息
  6. 所以結合 awk 進行過濾,再通過 watch 命令可以動態輸出查看結果
  7. 發現有多個軟中斷類型在變化,重點是 NET_RX 變化頻率超高,而且幅度也很大,它是網絡數據包接收軟中斷,暫且認為它是問題根源
  8. 既然跟網絡有關系,可以先通過 sar 命令查看系統網絡接收和發送的整體情況
  9. 然后可以看到接收的 PPS 會比接收的 BPS 大很多,做下運算,發現網絡幀會非常小,也就是常說的小包問題
  10. 接下來,通過 tcpdump 抓取 80端口的 tcp 協議網絡包,會發現大量來自  VM2 發送的 SYN 包,結合 sar 命令,確認是 SYN FLOOD 攻擊


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM