在 linux 中,tc 有二种控制方法 CBQ 和 HTB.HTB 是设计用来替换 CBQ 的.HTB比CBQ更加灵活,但是CPU 开销也更大,通常高速的链路会使用CBQ,一般而言HTB使用的更加广泛
我们对 tc 中的 HTB 的规则本质上是一个树形结构,包括三个基本的构成块:
队列规定 qdisc(queueing discipline) ,类(class)和分类器(Classifiers).
用来实现控制网络的收发速度.通过队列,linux可以将网络数据包缓存起来,然后根据用户的设置,在尽量不中断连接(如 tcp)的前提下来平滑网络流量.需要注意的是,linux 对接收队列的控制不够好,所以我们一般只用发送队列,即"控发不控收".它封装了其他两个主要 tc 组件(类和分类器).内核如果需要通过某个网络接口发送数据包,它都需要按照为这个接口配置的 qdisc 队列规则把数据包加入队列.然后,内核会尽可能多地从 qdisc里面取出数据包,把它们交给网络适配器驱动模块.
最简单的 QDisc 是 pfifo 它不对进入的数据包做任何的处理,数据包采用先入先出的方式通过队列.不过,它会保存网络接口一时无法处理的数据包.常有的队列规则包括 FIFO 先进先出,RED 随机早期探测,SFQ 随机公平队列和令牌桶 Token Bucket,类基队列 CBQ,CBQ 是一种超级队列,即它能够包含其它队列,甚至其它 CBQ.
class 用来表示控制策略.很显然,很多时候,我们很可能要对不同的IP实行不同的流量控制策略,这时候我们就得用不同的class来表示不同的控制策略了.
filter 用来将用户划入到具体的控制策略中(即不同的 class 中).比如,现在,我们想对xxa,xxb两个IP实行不同的控制策略(A,B),这时,我们可用 filter 将 xxa 划入到控制策略 A,将 xxb 划入到控制策略 B,filter 划分的标志位可用 u32 打标功能或 IPtables 的 set-mark (大多使用iptables 来做标记)功能来实现.
目前,tc可以使用的过滤器有:fwmark分类器,u32 分类器,基于路由的分类器和 RSVP 分类器(分别用于IPV6、IPV4)等;其中,fwmark 分类器允许我们使用 Linux netfilter 代码选择流量,而 u32 分类器允许我们选择基于 ANY 头的流量 .需要注意的是,filter (过滤器)是在QDisc 内部,它们不能作为主体.
1,添加规则
[root@ct-test ~]# tc qdisc add dev eth1 root handle 1: htb r2q 1
[root@ct-test ~]# tc class add dev eth1 parent 1: classid 1:1 htb rate 5mbit ceil 10mbit
[root@ct-test ~]# tc filter add dev eth1 parent 1: protocol ip prio 16 u32 match ip dst 192.168.3.153 flowid 1:1 #filter用来将用户划入到具体的控制策略中(即不同的class中)。
TC包括三个基本的构成块: 队列规定qdisc(queueing discipline )、类(class)和分类器(Classifiers)
就可以限制192.168.3.153的下载速度为5Mbit最高可以10Mbit
r2q,是指没有default的root,使整个网络的带宽没有限制
2,查看添加的规则
[root@ct-test ~]# tc -s -d qdisc show dev eth1 #查看队列(用来实现控制网络的收发速度)
qdisc htb 1: r2q 1 default 0 direct_packets_stat 48846 ver 3.17
Sent 28638574 bytes 48870 pkts (dropped 0, overlimits 0 requeues 0)
[root@ct-test ~]# tc -s -d class show dev eth1 #查看类(class用来表示控制策略)
class htb 1:1 root prio 0 quantum 200000 rate 5Mbit ceil 10Mbit burst 2224b/8 mpu 0b overhead 0b cburst 2848b/8 mpu 0b overhead 0b level 0
Sent 14679 bytes 52 pkts (dropped 0, overlimits 0 requeues 0)
rate 202bit
lended: 52 borrowed: 0 giants: 0
tokens: 3568 ctokens: 2296
[root@ct-test ~]#
3,删除添加的规则
[root@ct-test ~]# tc qdisc del dev eth1 root
4,再次查看规则
[root@ct-test ~]# tc -s -d qdisc show dev eth1
qdisc pfifo_fast 0: bands 3 priomap 1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 326504 bytes 488 pkts (dropped 0, overlimits 0 requeues 0)
[root@ct-test ~]# tc -s -d class show dev eth1 #已删除
[root@ct-test ~]#
应用:
在一个网卡上建立tbf队列,并限制网卡的速度
tc qdisc add dev eth0 root tbf rate 51200kbit latency 50ms burst 200k
限制网卡eth0流出速度为51200kbit
ps:burst(缓冲区)参数很重要,不能设得太小。
比如:tc qdisc add dev eth0 root tbf rate 20Mbit latency 50ms burst 1000;burst设为1000,结果用iperf工具检测不到网速,后来设为1540就没问题了,查了好久才找到这个原因。
参考资料:
http://www.turbolinux.com.cn/turbo/wiki/doku.php?id=traffic-control:tc%E6%B5%81%E9%87%8F%E7%AE%A1%E7%90%86%E7%AE%80%E4%BB%8B