Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> 關於 Linux

Linux 使用 Shell 腳本監控高速網路流量:基於 /sys/class/net 統計介面

編輯:關於 Linux

傳統流量監控工具(iftop、nload、vnstat)依賴 libpcap 抓包分析,在 10Gbps+ 高速介面上 CPU 佔用極高甚至漏包。Linux 核心透過 /sys/class/net/<介面>/statistics/ 暴露介面級計數器(封包數、位元組數、錯誤、丟包),讀取無需複製封包內容,極適合高頻、低負擔流量統計。本文提供可直接部署的 Shell 腳本與解析邏輯。

核心統計檔案位置

/sys/class/net/eth0/statistics/
├── rx_bytes        # 接收位元組數
├── tx_bytes        # 傳送位元組數
├── rx_packets      # 接收封包數
├── tx_packets      # 傳送封包數
├── rx_errors       # 接收錯誤
├── tx_errors       # 傳送錯誤
├── rx_dropped      # 接收丟包
├── tx_dropped      # 傳送丟包
├── rx_fifo_errors  # FIFO 錯誤
├── tx_fifo_errors
├── rx_frame_errors
├── tx_carrier_errors
├── rx_compressed
├── tx_compressed
├── rx_multicast
└── collisions

數值為累計計數器(64 位元無號整數),核心驅動程式即時更新,讀取即為當前快照。

腳本 1:每秒封包率 (PPS) 監控

#!/bin/bash
# pps_monitor.sh - 監控指定介面每秒封包收發數
# 用法: ./pps_monitor.sh eth0

INTERVAL=1
IFACE=${1:-eth0}

if [[ ! -d "/sys/class/net/$IFACE/statistics" ]]; then
    echo "錯誤: 介面 $IFACE 不存在或無 statistics 目錄"
    exit 1
fi

echo "監控介面: $IFACE (間隔 ${INTERVAL}s)"
echo "時間                RX PPS      TX PPS"

while true; do
    R1=$(cat /sys/class/net/$IFACE/statistics/rx_packets)
    T1=$(cat /sys/class/net/$IFACE/statistics/tx_packets)
    sleep $INTERVAL
    R2=$(cat /sys/class/net/$IFACE/statistics/rx_packets)
    T2=$(cat /sys/class/net/$IFACE/statistics/tx_packets)
    
    RX_PPS=$((R2 - R1))
    TX_PPS=$((T2 - T1))
    
    printf "%s  %'12d  %'12d\n" "$(date '+%H:%M:%S')" $RX_PPS $TX_PPS
done

腳本 2:每秒頻寬 (bps/Bps) 監控

#!/bin/bash
# bw_monitor.sh - 監控指定介面每秒位元組/位元傳輸率
# 用法: ./bw_monitor.sh eth0

INTERVAL=1
IFACE=${1:-eth0}

if [[ ! -d "/sys/class/net/$IFACE/statistics" ]]; then
    echo "錯誤: 介面 $IFACE 不存在"
    exit 1
fi

echo "監控介面: $IFACE (間隔 ${INTERVAL}s)"
printf "%-10s  %'15s  %'15s  %'15s  %'15s\n" "時間" "RX Bytes/s" "TX Bytes/s" "RX bits/s" "TX bits/s"

while true; do
    RX1=$(cat /sys/class/net/$IFACE/statistics/rx_bytes)
    TX1=$(cat /sys/class/net/$IFACE/statistics/tx_bytes)
    sleep $INTERVAL
    RX2=$(cat /sys/class/net/$IFACE/statistics/rx_bytes)
    TX2=$(cat /sys/class/net/$IFACE/statistics/tx_bytes)
    
    RX_BPS=$((RX2 - RX1))
    TX_BPS=$((TX2 - TX1))
    RX_bps=$((RX_BPS * 8))
    TX_bps=$((TX_BPS * 8))
    
    printf "%-10s  %'15d  %'15d  %'15d  %'15d\n" \
        "$(date '+%H:%M:%S')" $RX_BPS $TX_BPS $RX_bps $TX_bps
done

腳本 3:完整健康度儀表板 (含錯誤/丟包率)

#!/bin/bash
# net_health.sh - 綜合介面健康度監控
IFACE=${1:-eth0}
INTERVAL=2

declare -A PREV
for f in /sys/class/net/$IFACE/statistics/*; do
    PREV[$(basename $f)]=$(cat $f)
done

echo "介面 $IFACE 健康度監控 (間隔 ${INTERVAL}s)"
printf "%-8s %'12s %'12s %'10s %'10s %'8s %'8s %'8s %'8s\n" \
    "時間" "RX_B" "TX_B" "RX_P" "TX_P" "RX_ERR" "TX_ERR" "RX_DRP" "TX_DRP"

while true; do
    sleep $INTERVAL
    declare -A CUR
    for f in /sys/class/net/$IFACE/statistics/*; do
        CUR[$(basename $f)]=$(cat $f)
    done
    
    RX_B=$((CUR[rx_bytes]-PREV[rx_bytes]))
    TX_B=$((CUR[tx_bytes]-PREV[tx_bytes]))
    RX_P=$((CUR[rx_packets]-PREV[rx_packets]))
    TX_P=$((CUR[tx_packets]-PREV[tx_packets]))
    RX_E=$((CUR[rx_errors]-PREV[rx_errors]))
    TX_E=$((CUR[tx_errors]-PREV[tx_errors]))
    RX_D=$((CUR[rx_dropped]-PREV[rx_dropped]))
    TX_D=$((CUR[tx_dropped]-PREV[tx_dropped]))
    
    printf "%-8s %'12d %'12d %'10d %'10d %'8d %'8d %'8d %'8d\n" \
        "$(date '+%H:%M:%S')" $RX_B $TX_B $RX_P $TX_P $RX_E $TX_E $RX_D $TX_D
    
    PREV=("${CUR[@]}")  # 陣列複製需 Bash 4.3+
    # 相容寫法: for k in "${!CUR[@]}"; do PREV[$k]=${CUR[$k]}; done
done

部署與使用技巧

1. 作為系統服務常駐輸出至日誌

# /etc/systemd/system/net-monitor@.service
[Unit]
Description=Network Interface Monitor for %i
After=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/bw_monitor.sh %i
StandardOutput=append:/var/log/net-monitor/%i.log
Restart=on-failure
User=nobody

[Install]
WantedBy=multi-user.target
mkdir -p /var/log/net-monitor
systemctl enable --now net-monitor@eth0

2. 整合至 Prometheus (Node Exporter 已內建)

Node Exporter 會自動收集 /sys/class/net/*/statistics/ 並暴露為 node_network_receive_bytes_total 等指標,生產環境建議直接使用 Node Exporter + Prometheus + Grafana,無需自寫腳本。

3. 多介面聚合腳本

#!/bin/bash
# aggregate_bw.sh - 統計所有實體介面總流量
INTERVAL=1
while true; do
    RX_TOT=0; TX_TOT=0
    for iface in /sys/class/net/*/statistics/rx_bytes; do
        [[ $iface =~ /sys/class/net/(.+)/statistics ]] && IFACE=${BASH_REMATCH[1]}
        [[ $IFACE =~ ^(lo|docker|veth|br-|virbr) ]] && continue  # 排除虛擬介面
        RX_TOT=$((RX_TOT + $(cat $iface)))
        TX_TOT=$((TX_TOT + $(cat ${iface/rx_bytes/tx_bytes})))
    done
    sleep $INTERVAL
    # 計算差值輸出...
done

效能優勢分析

指標libpcap 抓包/sys 統計介面
CPU 佔用 (10Gbps)高 (需複製封包至用戶空間)極低 (僅讀取計數器)
記憶體壓力大 (Ring Buffer)無
封包處理延遲有 (中斷、複製)零 (核心原子更新計數器)
可見封包內容是 (深度分析)否 (僅統計量)
適用場景封包級分析、異常排查高頻流量計費、頻寬監控、告警

注意事項

  • 計數器為 64 位元,極高流量長時間運行可能溢位(約 18 EB),核心會自動環繞,腳本減法計算仍正確(無號整數環繞特性)。
  • 虛擬介面(docker0、veth、br-)也有 statistics,監控實體流量時需過濾。
  • 某些驅動程式不支援完整統計檔案(如 rx_compressed),讀取時需容錯。
  • 容器內預設看宿主機介面統計,需 --cap-add=CAP_NET_ADMIN 或掛載 /sys/class/net 才能看到容器專屬介面。

總結

基於 /sys/class/net/statistics 的 Shell 腳本,提供零負擔、高頻率、生產級可用的高速網路流量監控能力。適合嵌入式裝置、無 Node Exporter 環境、快速臨時監控。長期運行建議遷移至 Node Exporter + Prometheus 體系,獲得持久化、告警、視覺化完整能力。

Copyright © Windows教程網 All Rights Reserved