linux中限制网卡带宽需区分场景:tbf适合全局限速(如tc qdisc add dev eth0 root tbf rate 5mbit),htb支持分层保障(如ssh保底512kbit、http限2mbit),wondershaper则提供一键上下行限速。

在Linux中限制某个网卡接口的传输带宽速度,是为了防止某项业务突发流量挤占全部出口带宽,导致SSH管理中断、监控失联或同机其他服务响应迟缓。必须明确:tc命令仅作用于出向(egress)流量,且只对物理网卡(如eth0、ens33)生效,对lo、docker0、veth等虚拟接口直接配置会静默失败。
用TBF快速限全局限速(适合压测/应急)
这一步操作起来很简单,直接执行单条命令即可生效,适合临时压测或紧急封顶。
先清除可能残留的规则:sudo tc qdisc del dev eth0 root 2>/dev/null
再用令牌桶(TBF)将eth0出口总带宽限制为5Mbps:sudo tc qdisc add dev eth0 root tbf rate 5mbit burst 16kbit latency 50ms
burst值太小会导致TCP重传激增、吞吐骤降;太大则失去限速意义。16kbit是千兆网卡下的安全起点,万兆网卡需按比例上调。latency设为50ms是平衡延迟与缓冲区大小的经验值,低于20ms易丢包,高于100ms会显著拖慢交互响应。
用HTB构建可保障的分层限速(生产环境推荐)
单纯限速会让关键服务(如SSH、API健康检查)在高峰时被饿死。HTB能同时设定最小保障带宽和最大上限,让流量“有保底、不越界”。以下以保障SSH(22端口)512kbit、限制HTTP(80端口)为2mbit为例:
第一步:清空并创建HTB根队列:sudo tc qdisc del dev eth0 root 2>/dev/null && sudo tc qdisc add dev eth0 root handle 1: htb default 30
第二步:建立根类,声明总出口能力为10mbit:sudo tc class add dev eth0 parent 1: classid 1:1 htb rate 10mbit
第三步:创建SSH保障类,rate=512kbit(最低可用),ceil=2mbit(突发上限):sudo tc class add dev eth0 parent 1:1 classid 1:2 htb rate 512kbit ceil 2mbit prio 1
第四步:创建HTTP限速类,rate=2mbit(强制均摊),ceil=2mbit(禁止借用):sudo tc class add dev eth0 parent 1:1 classid 1:10 htb rate 2mbit ceil 2mbit prio 2
第五步:绑定端口到对应类:sudo tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 22 0xffff flowid 1:2 && sudo tc filter add dev eth0 protocol ip parent 1:0 prio 2 u32 match ip dport 80 0xffff flowid 1:10
注意:u32匹配中的dport指目标端口,即本机对外提供服务的端口;若要限本机访问远端80端口的出流量,应改用sport 80
用wondershaper一键限上下行(新手友好)
如果你只需要粗粒度控制下载和上传速率,且不想手写tc命令,wondershaper是最省心的选择。它自动处理队列、分类、过滤器,并内置SFQ公平队列防止单连接霸占带宽。
Ubuntu/Debian安装:sudo apt install wondershaper
CentOS/RHEL(启用EPEL后):sudo yum install wondershaper
对eth0限下行2048kbps、上行512kbps:sudo wondershaper eth0 2048 512
解除限速:sudo wondershaper clear eth0
这条命令实际展开后包含约12条tc和iptables指令,但你完全不用关心底层——它已预设好SSH优先级、ICMP低延迟通道和批量流量隔离逻辑。
验证与排查限速是否生效
查看当前所有限速规则:sudo tc qdisc show dev eth0
查看各类统计计数:sudo tc -s class show dev eth0
实时观察eth0出向流量:sudo iftop -P -f "out port 22 or out port 80" -i eth0
如果tc qdisc show返回空,说明规则未加载成功;如果tc -s class中bytes字段长时间为0,大概率是filter匹配条件写错(比如把dport写成sport,或IP掩码未补0xffff)。











