1.?netem corrupt 5%
?的作用
功能說明
corrupt 5%
?表示?隨機修改 5% 的數據包內容(如翻轉比特位),模擬數據損壞。- 它本身不會直接丟棄或延遲數據包,而是讓接收端收到錯誤的數據(可能觸發校驗和失敗、協議層重傳等)。
為何帶寬驟降?
- 關鍵問題:
netem
?的?corrupt
?操作需要?逐包處理(修改數據包內容),這會引入顯著的?CPU 開銷。 - 性能瓶頸:
- 當發送速率極高(如 5.26 Gbps)時,
netem
?可能無法實時處理所有數據包,導致?隊列堆積。 - 默認情況下,
netem
?使用內核的?Qdisc 內核線程(軟中斷)處理數據包,其處理能力遠低于專用硬件(如網卡 DMA)。 - 當隊列滿時,內核會觸發?TCP 擁塞控制(如降低發送窗口),最終表現為帶寬驟降。
- 當發送速率極高(如 5.26 Gbps)時,
2. 驗證原因:觀察?netem
?隊列狀態
方法 1:檢查 Qdisc 隊列長度
bash
tc -s qdisc show dev enp4s0 |
輸出示例:
qdisc netem 1: root refcnt 2 limit 1000 packets # 默認隊列長度為 1000 包 | |
Sent 1234567 packets 567890123 bytes (123.45 MB) | |
dropped 0 overlimits 0 requeues 0 |
- 關鍵指標:
limit 1000 packets
:隊列最大容量。overlimits
:因隊列滿而丟棄的數據包數(若增加,說明隊列堆積)。- 若?
overlimits
?為 0 但帶寬仍驟降,可能是?netem
?處理延遲導致發送端主動降速。
方法 2:監控 CPU 使用率
bash
top -p $(pgrep -f "ksoftirqd") # 觀察軟中斷線程(處理 Qdisc) | |
mpstat -P ALL 1 # 查看各 CPU 核心負載 |
- 預期現象:
- 使用?
netem
?時,某個 CPU 核心的?si
(軟中斷)使用率會接近 100%。 - 高 CPU 負載會導致內核無法及時處理數據包,觸發發送端降速。
- 使用?
3. 為什么?corrupt
?比?delay
/loss
?更影響性能?
操作類型 | 內核處理開銷 | 典型帶寬影響 |
---|---|---|
delay | 低(僅修改時間戳) | 幾乎無影響(除非延遲極大) |
loss | 低(直接丟棄包) | 線性降速(如 5% 丟包 → 帶寬約降 5%) |
corrupt | 高(需逐包修改數據) | 可能引發指數級降速(因擁塞控制) |
corrupt
?的特殊性:- 修改數據包內容后,接收端的 TCP 棧會檢測到校驗和錯誤,觸發?快速重傳?或?RTO(超時重傳)。
- 重傳會導致發送端?降低發送窗口,進一步限制帶寬。
- 若?
netem
?處理速度跟不上發送速率,隊列堆積會加劇這一過程。
4. 如何驗證是?netem
?性能瓶頸而非其他問題?
實驗 1:替換為?loss
?測試
# 移除原有規則 | |
sudo tc qdisc del dev enp4s0 root | |
# 添加 5% 丟包規則(低開銷) | |
sudo tc qdisc add dev enp4s0 root netem loss 5% | |
# 重新運行 iperf3 | |
iperf3 -c <接收端IP> -t 30 |
預期結果:
- 帶寬會線性下降約 5%(如從 5.26 Gbps 降至 ~5 Gbps),不會驟降至 7 Mbps。
- 說明?
corrupt
?的高開銷是主因。
實驗 2:降低發送速率測試
bash
# 限制 iperf3 發送速率為 100 Mbps | |
iperf3 -c <接收端IP> -b 100M -t 30 | |
# 同時保持 netem corrupt 5% | |
sudo tc qdisc add dev enp4s0 root netem corrupt 5% |
預期結果:
- 帶寬可能穩定在 ~95 Mbps(5% 損壞影響),不會驟降。
- 說明高發送速率下?
netem
?處理能力不足。
5. 解決方案
方案 1:降低?netem
?處理壓力
-
減少影響范圍:
# 僅對特定流量應用 corrupt(如通過 iptables 標記)
sudo iptables -A PREROUTING -p tcp --dport 1234 -j MARK --set-mark 1
sudo tc qdisc add dev enp4s0 root handle 1: prio
sudo tc filter add dev enp4s0 parent 1: protocol ip prio 1 u32 match ip dport 1234 0xffff action mirred egress redirect dev netem_if
# 需創建虛擬設備或使用其他方法限制流量
(更簡單的方法是直接降低測試速率)
-
降低損壞比例:
sudo tc qdisc change dev enp4s0 root netem corrupt 0.5% # 從 5% 降至 0.5%
方案 2:使用硬件加速(如 DPDK)
- 若需高精度模擬損壞且保持高性能,可考慮:
- 使用 DPDK 的?
pktgen
?工具(用戶態處理,繞過內核瓶頸)。 - 專用網絡測試儀(如 Ixia、Spirent)。
- 使用 DPDK 的?
方案 3:接受性能下降(測試目的)
- 如果目標是?驗證系統在錯誤下的行為(如 TCP 重傳、應用層超時),帶寬驟降是合理現象。
- 此時應關注:
- 接收端是否正確處理損壞數據(如 TCP 校驗和失敗)。
- 應用層是否觸發容錯機制(如重試、降級)。
6. 總結
現象 | 原因 | 是否正常 |
---|---|---|
帶寬從 5.26 Gbps 驟降至 7 Mbps | netem corrupt 5% ?的高 CPU 開銷導致隊列堆積,觸發 TCP 擁塞控制 | 正常(但需明確測試目標) |
corrupt ?比?loss /delay ?更影響性能 | 修改數據包內容需要逐包處理,開銷遠高于丟棄或延遲 | 預期行為 |
低發送速率下?corrupt ?不導致驟降 | netem ?處理能力足夠時,帶寬僅受損壞比例影響 | 驗證了瓶頸來源 |
建議:
- 若需測試高帶寬下的錯誤處理,改用?
loss
?或?delay
,或降低?corrupt
?比例。 - 若需精確模擬損壞,接受性能下降,并監控 TCP 重傳等指標。
# 延遲
sudo tc qdisc add dev enp1s0 root netem delay 100ms 1000ms
# 服務器限速(丟棄超額包)
?tc qdisc add dev enp1s0 root netem loss 10% ?丟棄?
# 在接收端添加損壞規則# 5% 概率損壞包
sudo tc qdisc add dev enp1s0 handle 1: root netem corrupt 5%
限制發送端帶寬
# sudo tc qdisc add dev enp4s0 root netem rate 100mbit
#sudo tc qdisc add dev eth0?root tbf rate 100mbit burst 32kbit latency 400ms
使用?tc
(流量控制工具)在網卡?eth0
?上創建一個?TBF(令牌桶過濾器)?根隊列規則,限制出口流量速率為?100Mbps,允許突發流量最多?32Kbit,并設置最大延遲為?400毫秒,從而實現基礎的流量整形和限速。
刪除
#tc qdisc del dev enp4s0 root
查看
#tc qdisc show dev enp4s0?
無法識別?netem
?隊列規則(qdisc)類型,通常是因為缺少必要的內核模塊或配置。以下是解決步驟:
1. 檢查內核模塊是否加載
netem
?需要?sch_netem
?內核模塊支持。運行以下命令檢查并加載模塊:
sudo modprobe sch_netem |
如果模塊不存在,可能需要安裝內核擴展包(見步驟2)。
2. 安裝內核擴展包(如未安裝)
在基于RHEL/CentOS的系統上,確保安裝了內核擴展包:
sudo yum install kernel-modules-extra # CentOS/RHEL 7/8 | |
# 或 | |
sudo dnf install kernel-modules-extra # Fedora/RHEL 9+ |
3. 驗證模塊是否加載
運行以下命令確認模塊已加載:
lsmod | grep netem |
如果看到?sch_netem
,則模塊已加載。
4. 重新嘗試添加qdisc
加載模塊后,重新執行你的命令:
sudo tc qdisc add dev ens22f0 root netem rate 100mbit |