Linux TC (Traffic Control 流控工具)

基本操作

  1. 清除现有的qdisc
tc qdisc del root dev eth0

Qdisc

Classless Qdisc
  1. 负责流量基本管理,包括流量整形、排序、限速等

  2. 不能在其上新建qdisc分支(即class)

  3. 分类

    • fifo_fast:没有自定义规则时的默认qdisc,直接对packet先进先出

    • tbf: Token Bucket Filter,令牌桶过滤,以一定速率发放token,对流量进行限速。token用完时,packet等待,如果等待超时(latency)将被dropped。token堆积时将允许网络burst

      tc qdisc add dev ppp0 root tbf rate 220kbit latency 50ms burst 1540
      // 限速220kbit,超时时间50ms,最高1540kbit
      
    • sqf: Stochastic Fairness Queueing,随机公平排序,将每个conversation(连接?)算作一个队列,每次随机从中选择其中一个conversation中的packet发送。其随机本质是采用哈希,同时每隔一定时间替换(perturb)哈希算法

      tc qdisc add dev eth0 root sfq perturb 10
      
    • CoDel and Fair Queueing CoDel

Classful Qdisc
  1. 允许在其上增添qdisc分支,比如filter规则等。新建的qdisc可以为classful或classless

  2. qdisc分支称作class,采用classid编号命名,而 parent 代指该class的母亲节点。命名方式为 x:y,其中 x 为root的名称一般为 1: ,而子类则类似于 1:10. 注意所有x和y不一定为母子关系,因为此处x 必为root,比如下面HTB的例子中 1:1 为root子节点,而 1:101:201:301:1 子节点

  3. Hierarchical Token Bucket (HTB)

    • 用于对根据目的对有限的带宽进行分层限流
    # This line sets a HTB qdisc on the root of eth0, and it specifies that the class 1:30 is used by default. It sets the name of the root as 1:, for future references.
    tc qdisc add dev eth0 root handle 1: htb default 30
    
    # This creates a class called 1:1, which is direct descendant of root (the parent is 1:), this class gets assigned also an HTB qdisc, and then it sets a max rate of 6mbits, with a burst of 15k
    tc class add dev eth0 parent 1: classid 1:1 htb rate 6mbit burst 15k
    
    # The previous class has this branches:
    
    # Class 1:10, which has a rate of 5mbit
    tc class add dev eth0 parent 1:1 classid 1:10 htb rate 5mbit burst 15k
    
    # Class 1:20, which has a rate of 3mbit
    tc class add dev eth0 parent 1:1 classid 1:20 htb rate 3mbit ceil 6mbit burst 15k
    
    # Class 1:30, which has a rate of 1kbit. This one is the default class.
    tc class add dev eth0 parent 1:1 classid 1:30 htb rate 1kbit ceil 6mbit burst 15k
    
    # Martin Devera, author of HTB, then recommends SFQ for beneath these classes:
    tc qdisc add dev eth0 parent 1:10 handle 10: sfq perturb 10
    tc qdisc add dev eth0 parent 1:20 handle 20: sfq perturb 10
    tc qdisc add dev eth0 parent 1:30 handle 30: sfq perturb 10
    

Filter

  1. 仅用于Classful Qdisc

  2. 可仅采用tc或tc + iptables的方式

    • tc only

      # This command adds a filter to the qdisc 1: of dev eth0, set the
      # priority of the filter to 1, matches packets with a
      # destination port 22, and make the class 1:10 process the
      # packets that match.
      tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dport 22 0xffff flowid 1:10
      
      # This filter is attached to the qdisc 1: of dev eth0, has a
      # priority of 2, and matches the ip address 4.3.2.1 exactly, and
      # matches packets with a source port of 80, then makes class
      # 1:11 process the packets that match
      tc filter add dev eth0 parent 1: protocol ip prio 2 u32 match ip src 4.3.2.1/32 match ip sport 80 0xffff flowid 1:11
      
    • tc + iptables

      // 对于标记有6的包,用1:30 class处理
      tc filter add dev eth0 protocol ip parent 1: prio 1 handle 6 fw flowid 1:30
      // 利用iptables的fwmark方法标记packet
      iptables -A PREROUTING -t mangle -i eth0 -j MARK --set-mark 6
      

基本概念

  1. noqueue 用于虚拟设备默认qdisc,不能用于物理设备。无法通过 tc qdisc add noque 赋予,而应通过 tc qdisc del 删除虚拟设备qdisc得到。表示不要放入队列,直接发送(如果无法发送则丢弃)。
  2. pfifo_fast用于物理设备,无法用于虚拟设备。无法通过 tc qdisc add 赋予,而应通过 tc qdisc del 删除虚拟设备qdisc得到。
    • 内部包含3个class(又称band),这3个class的qdisc规则不允许用户更改
    • packet发送顺序:class 1 先于 class 2 先于 class 3,同级按先入先出处理。无限速、无延迟。
    • 当高优先级流量超过设备处理能力时,低优先级流量将不被发送,可能会导致低优先级流量饥饿,特别是tcp连接
    • IP Header中的TOS会对应转化成优先级,不同优先级与class 1-3有对应关系
  3. prio 非常类似于pfifo_fast ,但是允许自定义class和classifier
    • 当采用默认值时,与pfifo_fast一样
    • 参数 bands 3 指定具备的class数量(2~16),默认值为3,对应于N:1 N:2 ... N:NUMBER
    • 总共具有16个优先级,与bands有对应关系
    • priomap class_for_prio_0 class_for_prio_1 ... class_for_prio_15,此处的class数字代表n+1,比如0代表class 1.
    • class内部规则与pfifo_fast 一致,可能出现低优先级流量饥饿。但可以选择为class定义一个qdisc限流规则(如tbf)
  4. 虚拟设备与物理设备的差异
    • traffic engine处理方式几乎一致,但存在下列差异
    • 由于虚拟设备一般只需对packet处理后便发送到下一个device,故packet一般不需要放到队列中等待处理。故所有对队列进行简单的重排序的qdisc都将失效,比如pfifo_fastcbqsfqprio等。而其他诸如改变发送速率的qdisc将保留
    • 设备默认创建时,物理设备qdisc时pfifo_fast,虚拟设备是noqueue
  5. root(egress)ingress 分别针对出流量和入流量,但并非实际的qdisc规则,只是为了便于将traffic control规则关联到上面结构化而已
    • root 支持所有qdisc规则,而 ingress 不支持绑定子class,只能绑定filter。实际作用相当于对进入的流量限流而已
  6. handle
    • 所有class及classful qdisc均需要一个唯一的ID,由两部分组成 x:y
      • x 取值任意,但具有相同parent的类需要有相同的 x 。一般将直接附属在 root 上的对象取为1
      • y 为0时代表qdisc,其他值代表为class。(为0时可省略,故qdisc时必须用1:0或1: )
  7. class
    • 仅存在于classful qdisc中,如HTB和CBQ。每个类都可以包含任意多个class或单个qdisc
    • 每个class可以绑定任意多个filter
    • leaf class为qdisc中的终端class,包含一个qdisc而不包含子class
上一篇:81_Go基础_1_49 结构体别名


下一篇:Nginx+KeepAlived实现负载均衡高可用原理