在 Linux 下,可以通过 TC 控制网络的 QoS,主要就是通过队列的方式。
第一大类称为无类别排队规则(Classless Queuing Disciplines)。pfifo_fast 分为三个先入先出的队列,称为三个 Band。根据网络包里面 TOS,看这个包到底应该进入哪个队列。TOS 总共四位,每一位表示的意思不同,总共十六种类型。
通过命令行 tc qdisc show dev eth0,可以输出结果 priomap,也是十六个数字。在 0 到 2 之间,和 TOS 的十六种类型对应起来,表示不同的 TOS 对应的不同的队列。其中 Band 0 优先级最高,发送完毕后才轮到 Band 1 发送,最后才是 Band 2。
另外一种无类别队列规则叫作随机公平队列(Stochastic Fair Queuing)。
会建立很多的 FIFO 的队列,TCP Session 会计算 hash 值,通过 hash 值分配到某个队列。在队列的另一端,网络包会通过轮询策略从各个队列中取出发送。这样不会有一个 Session 占据所有的流量。
当然如果两个 Session 的 hash 是一样的,会共享一个队列,也有可能互相影响。hash 函数会经常改变,从而 session 不会总是相互影响。
还有一种无类别队列规则称为令牌桶规则(TBF,Token Bucket Filte)。
所有的网络包排成队列进行发送,但不是到了队头就能发送,而是需要拿到令牌才能发送。
令牌根据设定的速度生成,所以即便队列很长,也是按照一定的速度进行发送的。
当没有包在队列中的时候,令牌还是以既定的速度生成,但是不是无限累积的,而是放满了桶为止。设置桶的大小为了避免下面的情况:当长时间没有网络包发送的时候,积累了大量的令牌,突然来了大量的网络包,每个都能得到令牌,造成瞬间流量大增。
另外一大类是基于类别的队列规则(Classful Queuing Disciplines),其中典型的为分层令牌桶规则(HTB, Hierarchical Token Bucket)。
OpenvSwitch 支持两种:
- 对于进入的流量,可以设置策略 Ingress policy;
ovs-vsctl set Interface tap0 ingress_policing_rate=100000
ovs-vsctl set Interface tap0 ingress_policing_burst=10000
- 对于发出的流量,可以设置 QoS 规则 Egress shaping,支持 HTB。
构建一个拓扑图,来看看 OpenvSwitch 的 QoS 是如何工作的。
首先,在 port 上可以创建 QoS 规则,一个 QoS 规则可以有多个队列 Queue。
此文章为9月Day27学习笔记,内容来源于极客时间《趣谈网络协议》,推荐该课程。