Linux 操作系统原理 — tc 流量控制技术解析

news2025/1/26 15:50:37

目录

文章目录

  • 目录
  • Traffic Control
  • Traffic Control 的基本实现原理
    • 流量处理的三个层面
    • 流量处理的关键流程
    • 流量队列的类型
      • FIFO 队列
      • PFIFO_FAST 队列
      • SFQ 队列
      • 令牌桶队列
  • Kernel Traffic Control 的工作原理
    • Qdisc(队列描述)
    • Class(分类)
    • Filter(过滤器)
    • Policer(策略器)
  • 使用 tc CLI 进行流量控制的示例
    • 1. 创建队列
    • 2. 创建分类
    • 3. 设置过滤器
    • 4. 上行带宽限制
    • 5. 下行带宽限制
    • 6. 对指定 srcIP 进行限速
    • HTB 示例

Traffic Control

Traffic Control 技术主要用于提供以下 2 种网络服务类型:

  1. Bandwidth Management(带宽管理):管理流量在某个接口上的 Bandwidth Size。
  2. QoS(服务质量保障):保障流量在整个端到端路径上的服务质量。

Traffic Control 技术的本质就是在网络设备(包括:主机网卡、交换机、路由器等)的 Ingress 和 Egress 处使用一系列的 Queues(队列)来对数据报文进行排队,继而控制它们的发送顺序和速率。同时,还可以针对不同的 Queue 施加相应的 Policy(策略)。

根据数据报文的类型不同,通常还可以分为以下 2 种:

  1. L2 Frame Traffic Control
  2. L3 Packets Traffic Control

在本文中,我们主要讨论 Linux Kernel 中实现的 L3 Packets Traffic Control 及其对应的 tc CLI。

Traffic Control 的基本实现原理

流量处理的三个层面

最基本的 Traffic Control 实现原理应该分为 3 个不同的层面:

  1. 流量分类(Classifier):在 IP 网络中,常用 IP 5-tuple(srcIP、srcPort、dstIP、dstPort、Protocol)来粗粒度地标识一条 Flow(数据流)。也可以更细粒度的根据每个 Packet(数据包)的 Header 信息进行分类,例如:根据 IPv4 Header 种的 ToS 字段进行分类。Traffic Classifier(分类器)能把不同类型的 Flows 或 Packets 划分到不同的 Queues 中去。

在这里插入图片描述

  1. 流量标记(Marker):Traffic Marker 可以由应用程序或者网络设备来充当,并根据需要对 Packets 进行标记,例如:修改 IPv4 Header 中的 ToS 字段。以此辅助更加灵活且个性化的流量分类需求。
    在这里插入图片描述

  2. 流量策略(Policier):在完成了流量的分类和标记之后,Traffic Policier 可以根据不同的 Policies 对相应的 Traffic 进行 Controlling 和 Scheduling。
    在这里插入图片描述

流量处理的关键流程

更具体而言,下图所示是一个常见的从 Ingress 到 Egress 的 Traffic Control 实现模型。

报文的标记与分类

  1. 标记:Packet 进入 Marker 之后,根据 Flow 的类型,为每个 Packets 打上不同的标记(e.g. DSCP 优先级)。
  2. 分类:通过将不同的 Filters 挂载到 Classifier 上实现灵活的分类配置,Classifier 根据 Filter 和标记类型对每个 Packets 进行分类,写入到不同的 Queues 中。

拥塞避免:Classifier 在将 Packets 写入 Queues 的过程中需要注意避免队列拥塞。可以通过实时监控网络资源(e.g. 队列或内存缓冲区)的使用情况来实现。如果拥塞水位超过阈值,则 Classifier 应该主动丢弃报文。

拥塞管理:通常而言,Traffic Control 只能限制 Egress 的 Packets,而不能限制 Ingress 的 Packets,所以直接影响 Egress 的拥塞管理是 Traffic Control 的核心,在满足 Bandwidth Mgmt、QoS 等网络服务的前提下,还需要保障网络不会处于拥塞的危险中。主要通过以下手段来实现:

  1. 带宽管理:将流量限制在特定的带宽内。当流量超过额定带宽时,超过的部分将被丢弃。满足服务需求的同时,也可以防止个别业务或用户无限制地占用带宽。
  2. 流量塑形:主动调整流的输出速率,将超出带宽的流量缓存到内存中,再根据实际情况发出。使流量能够比较平稳地传送给下游设备,避免不必要的报文丢弃和拥塞。
  3. 接口限速:针对某个特定的网络接口设备,直接限制其 Ingress 或 Egress 的总速率。在粗粒度管理场景中,具有简单高效的配置效果。
  4. 流量调度:通过加载不同的 Scheduler(调度器)来实现相应的 Policy。

在这里插入图片描述

流量队列的类型

Queue 是实现 TC 的关键,在长久的发展过程中,针对不同的业务需求,也诞生了多种类型的 Queues 和算法。

FIFO 队列

最简单的是 FIFO(先入先出)队列,也是早期 Linux Kernel 默认使用的发包队列类型。当 IP Packet 从 TCP/IP Stack 传递到 Network Device Layer 之后,就进入到 TC Egress FIFO Queue,并以 NIC 所能支持的最大速率发送出去。

在这里插入图片描述

PFIFO_FAST 队列

PFIFO_FAST 队列是 FIFO 队列的改进版本,作为新版 Kernel 的默认队列类型。在 FIFO 队列的基础上,支持识别 IPv4 Header 中的 ToS(Type of Service,服务类型)字段,继而进入到不同的优先级 Queues 中,以此来实现对不同服务类型的 QoS 保障。

在这里插入图片描述

SFQ 队列

SFQ 公平队列,顾名思义,它对所有 IP Packets 一视同仁,常用于防止某一个 Client 或 Flow 占用过多的带宽。

在这里插入图片描述

令牌桶队列

令牌桶队列(Token Bucket)实现了令牌桶算法,该算法的设计比较简单:

  1. Bucket(桶)会以一定的 Rate(速率)产生 Tokens(令牌),并且 Bucket 的容量是有限的。
  2. 一个 Packet 对应一个 Token,进入到 Queue 中的 Packet 只有从 Bucket 中获得了 Token 之后才可以出队。
  3. Bucket 通过控制 Token 生成的 Rate,继而控制 Packet 出队的 Rate。
  4. 当没有 Packet 要出队时,Bucket 中的 Tokens 会累积起来,以应对 Burst(突发)流量。

可见,网络流量比较恒定的场景中适合使用较小的令牌桶,而经常有突发流量的网络则适合使用大的令牌桶。

常见的令牌桶算法和队列主要有 2 种:

  1. TBF(Token Bucket Filter,令牌桶过滤器)队列
    在这里插入图片描述
  2. HTB(Hierarchical Token Bucket,分层令牌桶)队列
    在这里插入图片描述

Kernel Traffic Control 的工作原理

下图所示,TC 位于 L3 Sub-system 的外边界。IP Packets 进入 L3 Sub-system 之前需要先经过 TC Ingress(入方向),IP Packets 从 L3 Sub-system 出来后也会经过 TC Egress(出方向)。下面再逐一介绍 Kernel Traffic Control 的组部分。

在这里插入图片描述

Qdisc(队列描述)

Qdisc(Queue describer,队列描述),在 Linux 中的每个 Network Interface 设备都可以关联一个 Qdisc。
在这里插入图片描述

当 Kernel 发送 IP Packets 时,首先在 L3 sub-system 完成 Routing 确定一个 Next Hop Interface,然后再把 Packets 入队到 Interface 关联的 Qdisc 队列中。最终由 Qdisc 来决定 Packet 的发送顺序和速率。

每个 Qdisc 都具有一个队列类型,例如前文中介绍过的 FIFO、SFQ、令牌桶队列等。从实现原理上,Qdisc 可分为两大类型:

  1. Classless Qdiscs(无类别队列):实现相对简单,因为无需对 Packets 进行分类。包括:PFIFO_FAST(先进现出,默认队列)、SFQ(随机公平队列)、TBF(令牌桶过滤器)、ID(前向随机丢包)等队列类型。Classless Qdiscs 只支持接受数据包、重新编排数据包、延迟或丢弃数据包,可以对整个网卡接口的流量进行整形,但不会细分各种情况。常用于简单的排序、限速和丢包场景。

  2. Classful Qdiscs(分类队列):实现复杂,必须要关联到 Class 和 Filter 这两个高级分类概念上。包括:HTB(Hierarchical Token Bucket,分层令牌桶)队列等。当数据包进入一个 Classful Qdiscs 后,就会被 Filter 分类到某一个 Class 中。每个 Class 又可以具有多个 Sub-classes 和 Filters。直到不再分类为止,数据包才最终确定进入一个队列中。

值得注意的是,每个 Network Interface 都可以同时具有 TC Ingress 和 Egress,但实际上 Ingress 只能使用 Classless Qdiscs,其被当作一个用于附加 Policer 来控制入站流量的对象。而 Egress 则可以使用 Classful Qdiscs,是 Traffic Control 的关键位置。

在这里插入图片描述

Class(分类)

Class 作用于 Classful Qdiscs(e.g. HTB),被设计成树状结构,虽然一个 Class 仅可以关联一个 Qdiscs。但是一个 Class 可以具有任意个 Sub-Classes。所以理论上 Class 可以无限扩展,这样的设计使得 Linux 流量控制系统具有了极大的可扩展性和灵活性。

在一棵 Class Tree 中,可能会具有多种 Class 类型:

  • Root Class(根分类)
  • Inner Class(内部分类)
  • Leaf Class(叶子分类)

叶子分类都拥有一个负责发送该类数据的 Qdiscs,而且这个 Qdisc 是可以被再次分类的。但需要注意的是,一个 Qdisc 只能包含与其类型相同的 Class。例如:HTB Qdisc 只能包含 HTB Class,CBQ Qdisc 不能包含 HTB Class。

在这里插入图片描述

Filter(过滤器)

Filter 由 Classifier(分类器)和 Policer(策略器)组成,可以关联到 Qdisc 也可以关联到 Inner Class。每一个 Class 都有一个 ID,filter 将根据这个 ID 与指定的 Class 相关联。

所有 Egress 的 Packets 首先会通过 Interface 的 Root Qdisc,接着被与 Root Qdisc 关联的 Filter 对 Packets 进行分类,进入子分类,然后由子分类下的 Filter 继续进行分类。所以,如果需要在 Leaf Class 上再实现分类,那就必须将 Filter 与 Leaf Class 的 Qdisc 关联起来,而不能直接与 Leaf Qdisc 相关联。

在这里插入图片描述

Policer(策略器)

Policer 只能配合 Filter 使用。Policer 只有两种操作,当流量高于用户指定值时执行一种操作,反之执行另一种操作。

Policing 和 Shaping 都是 Linux 流量控制中的基本组件,两者都可以对带宽进行限制。但不同的是,Shaping 能保存并延迟发送数据包,而 Policing 只会直接丢弃数据包。所以,想要丢弃数据包只能依靠 Policer。

使用 tc CLI 进行流量控制的示例

使用 TC 进行流量控制通常需要 4 个步骤:

  1. 为网卡接口配置一个 Qdisc;
  2. 在该队列上建立 Class;
  3. 根据需要,建立 Sub-qdisc 和 Sub-class;
  4. 为每个 Class 建立 Filter。

在这里插入图片描述

1. 创建队列

$ tc qdisc add dev eth0 root handle 1: htb default 11
  • dev eth0:表示操作网卡 eth0;
  • root:表示为 eth0 添加的是一个根队列;
  • handle 1:表示队列的句柄为 1:;
  • htb:表示要添加的队列为 HTB 队列;
  • default 11:是 htb 队列特有的参数,表示所有未分类的流量都将被分配给类别 1:11;

2. 创建分类

$ tc class add dev eth0 parent 1: classid 1:11 htb rate 40mbit ceil 40mbit
$ tc class add dev eth0 parent 1: classid 1:12 htb rate 10mbit ceil 10mbit
  • parent 1:表示父类别为根队列 1:
  • classid1:11:表示创建一个句柄为 1:11 的子类别
  • rate 40mbit:表示该子类别的带宽为 40mbit
  • ceil 40mbit:表示该子类别的最大带宽为 40mbit
  • burst 40mbit:表示该子类别的峰值带宽为 40mbit

3. 设置过滤器

$ tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 80 0xffff flowid 1:11
$ tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 25 0xffff flowid 1:12
  • protocol ip:表示该过滤器匹配的协议类型
  • prio 1:表示该过滤器的优先级。系统将按照从小到大的优先级顺序来执行过滤器,而对于相同的优先级,系统将按照执行命令的先后顺序执行过滤器。
  • u32:表示该过滤器的分类器,是最常用的分类器,命令中 u32 后面的部分用来匹配不同的数据流。
  • dport:表示匹配数据包的 Destination Port 字段,如果该字段的值与 Oxffff 进行 “与” 操作得到的结果是 80 的话,则匹配。
  • flowid 1:11:表示将把该数据包分配给类别 1:11,从而继承子类 1:11 的速率参数。

4. 上行带宽限制

$ tc qdisc del dev eth0 root
$ tc qdisc add dev eth0 root handle 1: htb

$ tc class add dev  eth0 parent 1: classid 1:1 htb rate  20mbit ceil 20mbit
$ tc class add dev  eth0 parent 1:1 classid 1:10 htb rate 10mbit ceil 10mbit
$ tc qdisc add dev  eth0 parent 1:10 sfq perturb 10

#  让 172.20.6.0/24 走默认队列,为了让这个 IP 的数据流不受限制
$ tc filter add dev eth0 protocol ip parent 1: prio 2  u32 match ip dst 172.20.6.0/24 flowid 1:1

# 默认让所有的流量都从特定队列通过,带宽受到限制
$ tc filter add dev eth0 protocol ip parent 1: prio 50 u32 match ip dst 0.0.0.0/0  flowid 1:10

5. 下行带宽限制

$ modprobe ifb
$ ip link set dev ifb0 up

$ tc qdisc add dev eth0 handle ffff: ingress
$ tc filter add dev eth0 parent ffff: protocol ip u32 match u32 0 0 action mirred egress redirect dev ifb0
$ tc qdisc add dev ifb0 root handle 1: htb default 10
$ tc class add dev ifb0 parent 1: classid 1:1 htb rate 10mbit 
$ tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 10mbit ceil 10mbit

6. 对指定 srcIP 进行限速

$ tc qdisc add dev ifb0 root handle 1: htb default 20

$ tc class add dev ifb0 parent 1: classid 1:1 htb rate 10000mbit
$ tc class add dev ifb0 parent 1:1 classid 1:10 htb rate 2000mbit
$ tc class add dev ifb0 parent 1:1 classid 1:20 htb rate 1000mbit
$ tc class add dev ifb0 parent 1:1 classid 1:30 htb rate 500mbit

$ tc filter add dev ifb0 protocol ip parent 1:0 prio 1 u32 match ip src 129.9.123.85 flowid 1:10
$ tc filter add dev ifb0 protocol ip parent 1:0 prio 1 u32 match ip src 129.9.123.89 flowid 1:20 
$ tc filter add dev ifb0 protocol ip parent 1:0 prio 1 u32 match ip src 129.9.123.88 flowid 1:20

HTB 示例

在这里插入图片描述

# add qdisc
$ tc qdisc add dev eth0 root handle 1: htb default 2 r2q 100

# add default class
$ tc class add dev eth0 parent 1:0 classid 1:1 htb rate 1000mbit ceil 1000mbit
$ tc class add dev eth0 parent 1:1 classid 1:2 htb prio 5 rate 1000mbit ceil 1000mbit
$ tc qdisc add dev eth0 parent 1:2 handle 2: pfifo limit 500

# add default filter
$ tc filter add dev eth0 parent 1:0 prio 5 protocol ip u32
$ tc filter add dev eth0 parent 1:0 prio 5 handle 3: protocol ip u32 divisor 256
$ tc filter add dev eth0 parent 1:0 prio 5 protocol ip u32 ht 800:: match ip src 192.168.0.0/16 hashkey mask 0x000000ff at 12 link 3:

# add egress rules for 192.168.0.9
$ tc class add dev eth0 parent 1:1 classid 1:9 htb prio 5 rate 3mbit ceil 3mbit
$ tc qdisc add dev eth0 parent 1:9 handle 9: pfifo limit 500
$ tc filter add dev eth0 parent 1: protocol ip prio 5 u32 ht 3:9: match ip src "192.168.0.9" flowid 1:9

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/631983.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电子元器件解析之电容(二)——电容分类与应用场景

书接上文:电子元器件解析之电容(一)——定义与性能参数:https://blog.csdn.net/weixin_42837669/article/details/131142286 摘要 本文总结了各种不同介质电容的特性,包括陶瓷电容、电解电容、薄膜电容等;同时对一些特殊场合的电容…

Transformer Block运算量

参考:Swin Transformer论文精读【论文精读】_哔哩哔哩_bilibili 在看朱毅老师讲解Swin Transformer论文时,里面有一个Transformer Block的计算复杂度的推导计算,感觉清晰明了,这里做一下记录,先说一下结果,…

Android:Handler

参考来源 参考来源 参考来源 参考来源 Handler机制(面试版) Binder/Socket用于进程间通信,而Handler消息机制用于同进程的线程间通信 handler机制是android系统运行的基础,它采用生产者,消费者模式进行设计。其中生产…

基于SSM的青少年编程学习系统设计与实现

摘 要:在智能技术飞速发展的今天,各国都努力争取在人工智能时代的发展中占据优势,青 少年编程教育就显得格外重要。不过,相比一些青少年编程教育发展更先进的国家,我国青少 年编程教育仍处在初级阶段,很多青…

服务器(裸机)如何安装Centos 7系统

1. 下载系统镜像(可以选择自己对应的版本) http://mirrors.aliyun.com/centos/7/isos/x86_64/2. 制作linux系统U盘 下载UltraISO制作工具并安装 再准备一个空U盘(注意:这个操作会将U盘内数据全部删除操作之前请将U盘内文件备份&…

Swift学习笔记(一)基础语法

文章目录 前言开发工具变量与常量变量和常量的定义和使用变量和常量的命名规范注释初识基本数据类型浮点型数据布尔型数据两种特殊的基本数据类型元组可选值类型 为类型取别名模拟面试 字符、字符串与集合类型字符串类型字符串的组合字符类型转义字符 字符串类型中的常用方法集…

Redis的大key

什么是 redis 的大 key redis 的大 key 不是指存储在 redis 中的某个 key 的大小超过一定的阈值,而是该 key 所对应的 value 过大对于 string 类型来说,一般情况下超过 10KB 则认为是大 key;对于set、zset、hash 等类型来说,一般…

K8s in Action 阅读笔记——【13】Securing cluster nodes and the network

K8s in Action 阅读笔记——【13】Securing cluster nodes and the network 13.1 Using the host node’s namespaces in a pod Pod中的容器通常在不同的Linux名称空间下运行,这使得它们的进程与其他容器或节点默认名称空间下运行的进程隔离开来。 例如&#xff…

初学Nginx要掌握哪些概念

文章目录 为什么要使用Nginx?什么是Nginx?Nginx的作用?反向代理负载均衡动静分离 为什么要使用Nginx? 小公司项目刚刚上线的时候,并发量小,用户使用的少,所以在低并发的情况下,一个…

Android 逆向安全行业前景如何?

前言 Android 逆向是指对已经发布的 Android 应用进行分析和研究,通过逆向工程,将 Android 应用中的底层实现原理、业务逻辑、源代码以及恶意行为等等信息进行破解和掌握。逆向工程可以让研究者深入了解 Android 应用的实现细节,从而识别和修…

算法刷题-数组-螺旋矩阵

59.螺旋矩阵 力扣题目链接 给定一个正整数 n,生成一个包含 1 到 n^2 所有元素,且元素按顺时针顺序螺旋排列的正方形矩阵。 示例: 输入: 3 输出: [ [ 1, 2, 3 ], [ 8, 9, 4 ], [ 7, 6, 5 ] ] 思路 这道题目可以说在面试中出现频率较高的题目&#x…

3.DIY可视化-拖拽设计1天搞定主流小程序-前后分离框架运行

3.DIY可视化-拖拽设计1天搞定主流小程序-前后分离框架运行 前言 话不多说,直接实操。一、导入 diygw-ui-admin项目到vscode 克隆项目 : git clone https://gitee.com/diygw/diygw-ui-admin.git进入项目 桌面 cmd 运行: cd diygw-ui-admin推荐使用yarn 也可参照后面直接使用npm…

react合成事件+底层原理+发展历程

React中的合成事件 合成事件是围绕浏览器原生事件,充当跨浏览器包装器的对象;它们将不同浏览器的行为合并为一个API,这样做是为了确保事件在不同浏览器中显示一致的属性!保证兼容性 合成事件的基本操作 基础语法:在JSX元素上,直…

2023蓝桥杯大学A组C++决赛游记+个人题解

Day0 发烧了一晚上没睡着,感觉鼻子被打火机烧烤一样难受,心情烦躁 早上6点起来吃了个早饭,思考能力完全丧失了,开始看此花亭奇谭 看了六集,准备复习数据结构考试,然后秒睡 一睁眼就是下午2点了 挂了个…

交通 | GAMS快速入门及其在运输问题求解的应用

推文作者​:AmieeXue 第一部分 GAMS编程求解运输问题 GAMS,全称The General Algebraic Modeling System,是一款通用的高级数学建模工具,它支持线性规划、非线性规划、混合整数规划问题、二次约束规划(QCP)…

《面试1v1》List

我是 javapub,一名 Markdown 程序员从👨‍💻,八股文种子选手。 《面试1v1》 连载中… 面试官: 小伙子,听说你对Java集合挺在行的? 候选人: 谢谢夸奖,我对Java集合还在学习中,只能算入门水平。特别是List这…

vue 3 第三十五章:集成 tailwind Css

文章目录 1. tailWind css介绍2. tailWind css基本使用2.1. 步骤一:安装Tailwind CSS2.2. 步骤二:创建配置文件2.3. 步骤三:配置PostCSS2.4. 步骤四:引入样式文件2.5. 步骤五:模板中使用tailWind css 3. 补充3.1. 语法…

【P60】JMeter Jtl 文件的 html 格式输出

文章目录 一、汇总报告(Summary Report)参数说明二、准备工作三、测试计划设计四、Jtl 文件的 html 格式输出 一、汇总报告(Summary Report)参数说明 可以查看事务或者取样器在某个时间范围内执行的汇总结果 使用场景&#xff1…

Shell脚本攻略:Linux防火墙(二)

目录 一、理论 1.SNAT 2.DNAT 3.tcpdump抓包工具 二、实验 1.SNAT实验 2.DNAT实验 3.tcpdump抓包 一、理论 1.SNAT (1)概念 SNAT又称源地址转换。 源地址转换是内网地址向外访问时,发起访问的内网ip地址转换为指定的ip地址 &#…

【软考系统规划与管理师笔记】第6篇 IT服务部署实施

这章基本也是管理概念,考试内容基本以教材为主 1 概述 IT服务部署实施是衔接IT服务规划设计与IT服务运营的中间阶段,负责对服务组 件进行客户化,并在充分满足客户要求的前提下,使用标准化的方法管理人员、资源、 技术和过程&…