Linux效能優化實戰CPU篇之軟中斷(三)

MXC肖某某發表於2022-03-03

一、軟中斷

1,中斷的定義

a>定義

  舉例:你點了一份外賣,在無法獲知外賣進度的情況下,配送員送外賣是不等人的,到了發現沒人取會直接走,所以你只能苦苦等著,時不時去門口看送到沒有,無法幹別的事情。優化方式就是約定讓配送員送到後打電話告知就行,這裡打電話就是屬於一種中斷。

  定義:中斷其實是一種非同步的事件處理機制,可以提高系統的併發處理能力。由於中斷處理程式會打斷其他程式的執行,所以為了較少對正常程式執行的排程的影響,中斷處理程式就需要儘可能快地執行。

b>問題

  舉例:如果定了兩份外賣,一份主食一份飲料,並且由兩個不同的配送進行配送,你與兩個配送員都約定了打電話取外賣。當第一份外賣送到時,你與配送員打了個長長的電話,商量發票的處理問題。那麼,第二個配送員到後給你打電話發現一直被佔線(關閉了中斷響應),第二個配送員之後走掉(丟失了一箇中斷)

  缺點:中斷處理程式在響應中斷時,會臨時關閉中斷。也就是會導致上一次的中斷處理完成前,其他中斷都不能響應,可能存在中斷丟失。

2,軟中斷

a>定義

  Linux將中斷處理過程分成了兩個階段,也就是上半部和下半部

  • 上半部用來快速處理中斷,它在中斷禁止模式下執行,主要處理跟硬體緊密相關的或時間敏感的工作。直接處理硬體請求,硬中斷快速響應
  • 半部用來延時處理上半部未完成的工作,通常以核心執行緒的方式執行。核心觸發,軟中斷延遲執行

  舉例:解決兩份外賣的問題,第一份外賣,上半部:與配送員溝通見面再談事情,然後結束通話;下半部:取外賣並商量發票問題。第二份外賣由於第一個配送員並未佔用過多時間,可以正常接聽。

  實際上,上半部會打斷CPU正在執行的任務,然後立即執行中斷處理程式。而下半部以核心執行緒的方式執行,並且每個CPU都對應一個軟中斷核心執行緒,名字為“ksoftirqd/CPU編號”,比如:0號CPU對應的軟中斷核心執行緒的名字為ksoftirqd/0

b>檢視軟中斷和核心執行緒

  proc檔案系統就是一種核心空間和使用者空間進行通訊的機制,可以用來檢視核心的資料結構,用來動態修改核心的配置。

  • /proc/softirqs 提供了軟中斷的執行情況
  • /proc/interrupts 提供了硬中斷的執行情況

  

  在檢視/proc/softirqs檔案內容時,需要注意一下兩點:

  1. 軟中斷的型別,也就是這個介面中第一列的內容。從第一列可以看到,軟中斷包括了10個類別,分別對應不同的工作型別。比如 NET_RX 表示網路接收的中斷,而 NET_TX 表示網路傳送中斷
  2. 軟中斷在不同CPU上的表現。正常情況下,同一種中斷在不同CPU上的累積次數應該差不多。比如 NET_RX 在CPU0 和 CPU1 上的中斷次數基本是 同一數量級,相差不大。不過TASKLET在不同CPU上的分佈並不均勻。TASKLET是最常用的軟中斷實現機制,每個TASKLET只執行一次就結束,並且只在呼叫它的函式所在的CPU上執行。

二、軟中斷CPU升高案例

  使用兩臺虛擬機器,其中一臺用作Web伺服器,來模擬效能問題;另一臺用作Web伺服器的客戶端

  Linux效能優化實戰CPU篇之軟中斷(三)

VM1上啟動應用

   

 VM2上測試應用

  

  使用hping3模擬請求,發現VM1系統響應變慢

  

VM1上分析,使用top

  

  可以檢視到,CPU負載為0,就緒佇列僅有1個running,CPU使用率僅為3.3%和4.4%,但都在軟中斷上,那麼分析問題有可能就出現在軟中斷上。

觀察proc檔案系統的軟中斷情況。其中引數指的是系統執行以來的累積中斷次數,故而需要關注中斷次數的變化速率

  

   其中TIMER(定時中斷)、NET_RX(網路接收)、SCHED(核心排程)、RCU(RCU鎖)等這幾個軟中斷都在不停變化。而其中NET_RX,也就是網路資料包接收軟中斷的變化速率最快。

sar工具使用,sar可以用來檢視系統的網路收發情況,不僅可以觀察網路收發的吞吐量(BPS,每秒收發的位元組數),還可以觀察網路收發的PPS(每秒收發的網路幀數)。

  

  • 第一列:報告的時間
  • 第二列:IFACE表示網路卡
  • 第三、四列:rxpck/s 和 txpck/s 分別表示每秒接收、傳送的網路幀數,也就是PPS
  • 第五、六列:rxkB/s 和 txkB/s 分別表示每秒接收、傳送的千位元組數,也就是BPS

  對網路卡eth0來說,每秒接收的網路幀數比較大,達到了12607,而傳送的網路幀數則比較小,只有6304;每秒接收的節數有664KB,傳送的位元組有 358 KB

  docker和veth9f6bbcd 的資料跟 eth0 基本一致,只是傳送與接收想法,傳送的資料較大而接收的資料較小。這是Linux內部網橋轉發導致的,不必關注。這是linux內部網路橋轉發導致的。分析eth0:接收的PPS較大為12607,但是BPS卻很小為664KB,計算為:664*1024/12607 = 54位元組,說明平均每個網路幀只有54位元組,很小的網路幀也就是小包問題。

採用tcpdump抓取eth0上的包檢視,通過-i eth0選項指定網路卡eth0,通過tcp port 80選項指定TCP協議的80埠:

  

 

   從tcpdump的輸出,可以發現:

  • 192.168.0.2.18238 > 192.168.0.30.80,表示網路幀從192.168.0.2的18238埠傳送到192.168.0.30的80埠,也就是從執行hping3機器的18238埠傳送網路幀,目的為Nginx所在機器的80埠。
  • Flag [S] 表示是一個SYN包。

  結合sar的發現,PPS超過12000,可以確定這就是從192.168.0.2這個地址傳送的SYN FLOOD攻擊。至於SYN FLOOD攻擊最簡單的解決方法,就是從交換機或者硬體防火牆中封掉來源IP,這樣SYNFLOOD網路幀就不會傳送到伺服器中。

 

   

 

 

   

相關文章