You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何编写通用Shell脚本实现物理网卡带宽限速(如将10G链路限制为1G等)

如何编写通用Shell脚本实现物理网卡带宽限速(如将10G链路限制为1G等)

我太懂你不想翻出积灰老hub的心情了!用Linux的tc命令配合TBF(Token Bucket Filter)确实是最省心的软件限速方案,不用折腾硬件还能灵活调整带宽。下面我就给你写一个通用Shell脚本,同时把那些让人头疼的参数计算讲明白,保证你能直接用、看得懂。

先理清核心参数逻辑

TBF实现限速的关键是三个参数,先把它们搞透:

  • rate:就是你想要模拟的目标带宽,比如10M、100M,这是核心控制项;
  • burst:突发流量上限,简单说就是允许短时间内超过rate的最大流量。计算逻辑一般结合网卡MTU和目标带宽,公式可以用(MTU * 8) * 5(5个MTU大小的包,足够应对大部分场景),或者rate * latency / 1000(latency是延迟,单位毫秒);
  • latency:令牌桶的等待延迟,意思是当流量超过rate时,最多等多久再处理。现在内核支持NO_HZ的情况下,不用纠结系统tick,设个100ms就很稳妥,既能保证流量平滑,又不会有明显延迟。

通用Shell脚本实现

直接上可运行的脚本,保存成link-bandwidth.sh后记得加执行权限chmod +x link-bandwidth.sh

#!/bin/bash

# 检查参数数量是否正确
if [ $# -ne 2 ]; then
    echo "用法: $0 <网卡名> <目标带宽,如10m|100m|1G|2.5G|10G>"
    exit 1
fi

IFACE=$1
TARGET_BW=$2

# 检查网卡是否存在
if [ ! -d "/sys/class/net/$IFACE" ]; then
    echo "错误:网卡 $IFACE 不存在!"
    exit 1
fi

# 获取网卡MTU值
MTU=$(cat "/sys/class/net/$IFACE/mtu")
# 设置延迟参数(固定100ms,通用场景足够)
LATENCY=100

# 把人类友好的带宽单位转换成bps(比特每秒)
case $TARGET_BW in
    10m)
        RATE=10000000
        ;;
    100m)
        RATE=100000000
        ;;
    1G)
        RATE=1000000000
        ;;
    2.5G)
        RATE=2500000000
        ;;
    10G)
        RATE=10000000000
        ;;
    *)
        echo "错误:不支持的带宽单位!请使用10m|100m|1G|2.5G|10G"
        exit 1
        ;;
esac

# 计算burst值:取MTU计算和带宽延迟计算的较大值,兼顾突发流量和带宽匹配
BURST_MTU=$((MTU * 8 * 5))
BURST_RATE=$((RATE * LATENCY / 1000))
BURST=$((BURST_MTU > BURST_RATE ? BURST_MTU : BURST_RATE))

# 先清除网卡上已有的tc规则(避免新旧规则冲突)
echo "正在清除 $IFACE 上的旧限速规则..."
tc qdisc del dev $IFACE root 2>/dev/null

# 添加新的TBF限速规则
echo "正在将 $IFACE 限速为 $TARGET_BW..."
tc qdisc add dev $IFACE root tbf rate $RATE burst $BURST latency $LATENCY

if [ $? -eq 0 ]; then
    echo "限速成功!当前 $IFACE 带宽限制为 $TARGET_BW"
else
    echo "错误:限速失败,请确保以root权限运行!"
    exit 1
fi

脚本使用说明

  1. 权限要求:必须用root或sudo运行,因为tc命令需要管理员权限;
  2. 使用示例
    • 把eth0限速为100M:sudo ./link-bandwidth.sh eth0 100m
    • 恢复网卡原带宽(清除规则):sudo tc qdisc del dev eth0 root
  3. 灵活调整:要是需要其他带宽档位,直接在脚本的case分支里加对应的数值就行,比如加个500m)对应RATE=500000000

额外注意事项

  • 脚本默认限制的是**出口(egress)**带宽,如果需要限制入口(ingress),得配合tc ingressfilter规则实现,逻辑稍复杂,有需要可以再细聊;
  • 测试限速是否生效,推荐用iperf3工具:在另一台机器跑iperf3 -s,你的机器跑iperf3 -c <对方IP>,就能看到实际带宽是否符合预期;
  • 如果限速后出现丢包,可适当调大burst值,比如把脚本里的*5改成*10,给突发流量更多缓冲空间。

备注:内容来源于stack exchange,提问作者olh

火山引擎 最新活动