You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash脚本执行tc流量控制命令结果异常,求技术排查指导

排查流量整形失效问题的核心方向与原因解析

咱们先拆解你遇到的几个核心问题:速率远超设定值、默认队列删不掉、流量波动,这些问题大多和tc的配置逻辑以及流量方向的误解有关。

一、为什么上传速率远高于整形值?

这是最关键的问题,你大概率踩了tc流量整形的经典坑——流量方向搞反了:

  • tc默认的root qdisc是用来处理出口(egress)流量的,也就是服务器向外发送的流量;而你要限制的是客户端上传到服务器的流量,这属于服务器的入口(ingress)流量,直接在ens3的root配置HTB完全不会影响入口流量,相当于你在限制服务器发出去的速度,而客户端上传的流量根本没经过这个整形规则。
  • 另外,你的脚本每次删除root qdisc再重建,这个过程中会有短暂的“无规则窗口”,流量可以不受限制地通过;而且用while循环计算时间的方式不够可靠,可能导致整形规则的切换不及时。

二、为什么无法删除pfifo_fast队列?

pfifo_fast是Linux内核默认的出口qdisc,当你删除自定义的root qdisc后,内核会自动恢复这个默认队列,所以你看到的不是残留的旧规则,而是内核自动补上的默认规则。而且这个队列和你要限制的入口流量完全无关,删它自然没用。

三、为什么会出现80kbit设定却跑出640kbit的情况?

这大概率是单位混淆导致的:

  • 你脚本里用的是kbit(千比特每秒),但如果客户端或服务器的测速工具显示的是KB/s(千字节每秒),那1KB/s=8kbit/s,80KB/s刚好等于640kbit/s。你需要确认测速结果的单位是比特还是字节,避免误解。

具体排查与修复步骤

1. 修正流量方向:处理入口流量

要限制服务器接收的上传流量,需要用ifb虚拟设备把入口流量镜像到出口方向处理(因为HTB只能处理出口流量),步骤如下:

# 加载ifb模块
sudo modprobe ifb
# 启用ifb0设备
sudo ip link set dev ifb0 up
# 在ens3上添加入口qdisc
sudo tc qdisc add dev ens3 ingress
# 将所有入口IP流量镜像到ifb0
sudo tc filter add dev ens3 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0

之后所有的HTB规则都要配置在ifb0上,而不是ens3。

2. 优化脚本的tc配置逻辑

你的脚本不需要每次删除整个qdisc,直接修改class的速率即可,而且用sleep代替while循环更可靠:

#!/bin/bash
datenrate=80
datenrate2=40

echo "setting datarate to ${datenrate}kbit"
touch started.info

# 配置ifb0的初始整形规则
sudo tc qdisc add dev ifb0 handle 1: root htb default 11
sudo tc class add dev ifb0 parent 1: classid 1:1 htb rate ${datenrate}kbit
sudo tc class add dev ifb0 parent 1:1 classid 1:11 htb rate ${datenrate}kbit
echo "worked"

# 等待10秒
sleep 10

echo "10 sec over - setting up a datarate drop to ${datenrate2} kbit"
# 直接修改class的速率,无需重建qdisc
sudo tc class change dev ifb0 parent 1: classid 1:1 htb rate ${datenrate2}kbit
sudo tc class change dev ifb0 parent 1:1 classid 1:11 htb rate ${datenrate2}kbit
touch calledthrottle.info

# 再等待10秒
sleep 10

# 恢复正常流量
sudo tc qdisc del dev ens3 ingress
sudo tc qdisc del dev ifb0 root
sudo ip link set dev ifb0 down
echo "set to normal"
touch ended.info

3. 验证配置是否生效

配置后执行以下命令确认规则:

# 查看ifb0的qdisc配置
tc qdisc show dev ifb0
# 查看ifb0的class配置
tc class show dev ifb0
# 查看流量统计,确认是否有整形动作
tc -s qdisc show dev ifb0

如果看到HTB规则存在,且统计中有数据包被标记或丢弃,说明配置生效了。

为什么会有超出整形吞吐量的帧通过?

主要有两个原因:

  1. 规则未覆盖目标流量:之前的配置完全没处理入口流量,所以客户端上传的帧直接绕过了整形规则;
  2. 规则切换间隙的无限制窗口:旧脚本中删除再重建qdisc的过程中,会有短暂的时间没有任何整形规则,流量可以全速通过;
  3. 默认队列的优先级:如果你的规则配置有误,部分高优先级的流量可能会被默认的pfifo_fast队列优先处理,绕过HTB的限制。

内容的提问来源于stack exchange,提问作者Fulion

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:58:09