流量控制
最后更新于
流量控制(Traffic Control, tc)是Linux内核提供的流量限速、整形和策略控制机制。它以qdisc-class-filter
的树形结构来实现对流量的分层控制 :
tc最佳的参考就是Linux Traffic Control HOWTO,详细介绍了tc的原理和使用方法。
从上图中可以看到,tc由qdisc、fitler和class三部分组成:
qdisc通过队列将数据包缓存起来,用来控制网络收发的速度
class用来表示控制策略
filter用来将数据包划分到具体的控制策略中
qdisc通过队列将数据包缓存起来,用来控制网络收发的速度。实际上,每个网卡都有一个关联的qdisc。它包括以下几种:
[p|b]fifo
:简单先进先出
pfifo_fast
:根据数据包的tos将队列划分到3个band,每个band内部先进先出
red
:Random Early Detection,带带宽接近限制时随机丢包,适合高带宽应用
sfq
:Stochastic Fairness Queueing,按照会话对流量排序并循环发送每个会话的数据包
tbf
:Token Bucket Filter,只允许以不超过事先设定的速率到来的数据包通过 , 但可能允许短暂突发流量朝过设定值
cbq
:Class Based Queueing,借助EWMA(exponential weighted moving average, 指数加权移动均值 ) 算法确认链路的闲置时间足够长 , 以达到降低链路实际带宽的目的。如果发生越限 ,CBQ 就会禁止发包一段时间。
htb
:Hierarchy Token Bucket,在tbf的基础上增加了分层
prio
:分类优先算法并不进行整形 , 它仅仅根据你配置的过滤器把流量进一步细分。缺省会自动创建三个FIFO类。
注意,一般说到qdisc都是指egress qdisc。每块网卡实际上还可以添加一个ingress qdisc,不过它有诸多的限制
ingress qdisc不能包含子类,而只能作过滤
ingress qdisc只能用于简单的整形
如果相对ingress方向作流量控制的话,可以借助ifb( Intermediate Functional Block)内核模块。因为流入网络接口的流量是无法直接控制的,那么就需要把流入的包导入(通过 tc action)到一个中间的队列,该队列在 ifb 设备上,然后让这些包重走 tc 层,最后流入的包再重新入栈,流出的包重新出栈。
filter用来将数据包划分到具体的控制策略中,包括以下几种:
u32:根据协议、IP、端口等过滤数据包
fwmark:根据iptables MARK来过滤数据包
tos:根据tos字段过滤数据包
class用来表示控制策略,只用于有分类的qdisc上。每个class要么包含多个子类,要么只包含一个子qdisc。当然,每个class还包括一些列的filter,控制数据包流向不同的子类,或者是直接丢掉。