众所周知,在互联网诞生之初都是各个高校和科研机构相互通讯,并没有Linux流量控制方面的考虑和设计,IP协议的原则是尽可能好地为所有数据流服务,不同的数据流之间是平等的。然而多年的实践表明,这种原则并不是最理想的,有些数据流应该得到特别的照顾, 比如,远程登录的交互数据流应该比数据下载有更高的优先级。

针对不同的数据流采取不同的策略,这种可能性是存在的。并且,随着研究的发展和深入, 人们已经提出了各种不同的管理模式。IETF已经发布了几个标准, 如综合服务(Integrated Services)、区分服务(Diferentiated Services)等。其实,Linux内核从2 2开始,就已经实现了相关的流量控制功能。本文将介绍Linux中有关流量控制的相关概念, 用于Linux流量控制的工具TC的使用方法,并给出几个有代表性实例。

一、相关概念

由此可以看出, 报文分组从输入网卡(入口)接收进来,经过路由的查找, 以确定是发给本机的,还是需要转发的。如果是发给本机的,就直接向上递交给上层的协议,比如TCP,如果是转发的, 则会从输出网卡(出口)发出。网络流量控制通常发生在输出网卡处。虽然在路由器的入口处也可以进行流量控制,Linux也具有相关的功能, 但一般说来, 由于我们无法控制自己网络之外的设备, 入口处的Linux流量控制相对较难。本文将集中介绍出口处的流量控制。流量控制的一个基本概念是队列(Qdisc),每个网卡都与一个队列(Qdisc)相联系, 每当内核需要将报文分组从网卡发送出去, 都会首先将该报文分组添加到该网卡所配置的队列中, 由该队列决定报文分组的发送顺序。因此可以说,所有的Linux流量控制都发生在队列中,详细流程图见图1。

图1报文在Linux内部流程图

有些队列的功能是非常简单的, 它们对报文分组实行先来先走的策略。有些队列则功能复杂,会将不同的报文分组进行排队、分类,并根据不同的原则, 以不同的顺序发送队列中的报文分组。为实现这样的功能,这些复杂的队列需要使用不同的过滤器(Filter)来把报文分组分成不同的类别(Class)。这里把这些复杂的队列称为可分类(ClassfuI)的队列。通常, 要实现功能强大的Linux流量控制, 可分类的队列是必不可少的。因此,类别(class)和过滤器(Filter)也是流量控制的另外两个重要的基本概念。图2所示的是一个可分类队列的例子。

图2多类别队列

由图2可以看出,类别(CIass)和过滤器(Filter)都是队列的内部结构, 并且可分类的队列可以包含多个类别,同时,一个类别又可以进一步包含有子队列,或者子类别。所有进入该类别的报文分组可以依据不同的原则放入不同的子队列或子类别中,以此类推。而过滤器(Filter)是队列用来对数据报文进行分类的工具, 它决定一个数据报文将被分配到哪个类别中。

二、使用TC

在Linux中,Linux流量控制都是通过TC这个工具来完成的。通常, 要对网卡进行流量控制的配置,需要进行如下的步骤:

◆ 为网卡配置一个队列;

◆ 在该队列上建立分类;

◆ 根据需要建立子队列和子分类;

◆ 为每个分类建立过滤器。

在Linux中,可以配置很多类型的队列,比如CBQ、HTB等,其中CBQ 比较复杂,不容易理解。HTB(HierarchicaIToken Bucket)是一个可分类的队列, 与其他复杂的队列类型相比,HTB具有功能强大、配置简单及容易上手等优点。在TC 中, 使用"major:minor"这样的句柄来标识队列和类别,其中major和minor都是数字。

对于队列来说,minor总是为0,即"major:0"这样的形式,也可以简写为"major: 比如,队列1:0可以简写为1:。需要注意的是,major在一个网卡的所有队列中必须是惟一的。对于类别来说,其major必须和它的父类别或父队列的major相同,而minor在一个队列内部则必须是惟一的(因为类别肯定是包含在某个队列中的)。举个例子,如果队列2:包含两个类别,则这两个类别的句柄必须是2:x这样的形式,并且它们的x不能相同, 比如2:1和2:2。

下面,将以HTB队列为主,结合需求来讲述TC的使用。假设eth0出口有100mbit/s的带宽, 分配给WWW 、E-mail和Telnet三种数据流量, 其中分配给WWW的带宽为40Mbit/s,分配给Email的带宽为40Mbit/s, 分配给Telnet的带宽为20Mbit/S。

需要注意的是, 在TC 中使用下列的缩写表示相应的带宽:

◆ Kbps kiIobytes per second, 即"千字节每秒 ;

◆ Mbps megabytes per second, 即"兆字节每秒 ,

◆ Kbit kilobits per second,即"千比特每秒 ;

◆ Mbit megabits per second, 即"兆比特每秒 。

三、创建HTB队列

有关队列的TC命令的一般形式为:

1

2

#tc qdisc [add|change|replace|link] dev DEV [parent qdisk-id|

root][handle qdisc-id] qdisc[qdisc specific parameters]

首先,需要为网卡eth0配置一个HTB队列,使用下列命令:

#tc qdisc add dev eth0 root handle 1:htb default 11这里,命令中的"add 表示要添加,"dev eth0 表示要操作的网卡为eth0。"root 表示为网卡eth0添加的是一个根队列。"handle 1: 表示队列的句柄为1:。"htb 表示要添加的队列为HTB队列。命令最后的"default 11 是htb特有的队列参数,意思是所有未分类的流量都将分配给类别1:11。

四、为根队列创建相应的类别

有关类别的TC 命令的一般形式为:

1

2

#tc class [add|change|replace] dev DEV parent qdisc-id 

[classid class-id] qdisc [qdisc specific parameters]

可以利用下面这三个命令为根队列1创建三个类别,分别是1:1 1、1:12和1:13,它们分别占用40、40和20mb[t的带宽。

1

#tc class add dev eth0 parent 1: classid 1:1 htb rate 40mbit ceil 40mbit  

#tc class add dev eth0 parent 1: classid 1:12 htb rate 40mbit ceil 40mbit  

#tc class add dev eth0 parent 1: cllassid 1:13 htb rate 20mbit ceil 20mbit

命令中,"parent 1:"表示类别的父亲为根队列1:。"classid1:11"表示创建一个标识为1:11的类别,"rate 40mbit"表示系统

将为该类别确保带宽40mbit,"ceil 40mbit",表示该类别的最高可占用带宽为40mbit。

五、为各个类别设置过滤器

有关过滤器的TC 命令的一般形式为:

1

2

3

#tc filter [add|change|replace] dev DEV [parent qdisc-id

|root] protocol protocol prio priority filtertype [filtertype 

specific parameters] flowid flow-id

由于需要将WWW、E-mail、Telnet三种流量分配到三个类别,即上述1:11、1:12和1:13,因此,需要创建三个过滤器,如下面的三个命令:

1

#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 prtocol ip parent 1:0 prio 1 u32 match ip dport 25 0xffff flowid 1:12  

#tc filter add dev eth0 protocol ip parent 1:0 prio 1 u32 match ip dport 23 oxffff flowid 1:13

这里,"protocol ip"表示该过滤器应该检查报文分组的协议字段。"prio 1" 表示它们对报文处理的优先级是相同的,对于不同优先级的过滤器, 系统将按照从小到大的优先级。

顺序来执行过滤器, 对于相同的优先级,系统将按照命令的先后顺序执行。这几个过滤器还用到了u32选择器(命令中u32后面的部分)来匹配不同的数据流。以第一个命令为例,判断的是dport字段,如果该字段与Oxffff进行与操作的结果是80,则"flowid 1:11" 表示将把该数据流分配给类别1:1 1。更加详细的有关TC的用法可以参考TC 的手册页。

六、复杂的实例

在上面的例子中, 三种数据流(www、Email、Telnet)之间是互相排斥的。当某个数据流的流量没有达到配额时,其剩余的带宽并不能被其他两个数据流所借用。在这里将涉及如何使不同的数据流可以共享一定的带宽。

首先需要用到HTB的一个特性, 即对于一个类别中的所有子类别,它们将共享该父类别所拥有的带宽,同时,又可以使得各个子类别申请的各自带宽得到保证。这也就是说,当某个数据流的实际使用带宽没有达到其配额时, 其剩余的带宽可以借给其他的数据流。而在借出的过程中,如果本数据流的数据量增大,则借出的带宽部分将收回, 以保证本数据流的带宽配额。

下面考虑这样的需求, 同样是三个数据流WWW、E-mail和Telnet, 其中的Telnet独立分配20Mbit/s的带宽。另一方面,VWVW 和SMTP各自分配40Mbit/s。同时,它们又是共享的关系, 即它们可以互相借用带宽。如图3所示。

图三

需要的TC命令如下:

1

2

3

4

5

6

7

8

#tc qdisc add dev eth0 root handle 1: htb default 21  

#tc class add dev eth0 partent 1: classid 1:1 htb rate 20mbit ceil 20mbit  

#tc class add dev eth0 parent 1: classid 1:2 htb rate 80mbit ceil 80mbit  

#tc class add dev eth0 parent 1:2 classid 1:21 htb rate 40mbit ceil 20mbit  

#tc class add dev eth0 parent 1:2 classid 1:22 htb rate 40mbit ceil 80mbit  

#tc filter add dev eth0 protocol parent 10 prio 1 u32 match ip dport 80 0xffff flowid 1:21  

#tc filter add dev eth0 protocol parent 1:0 prio 1 u32 match ip dport 25 0xffff flowid 1:22  

#tc filter add dev eth0 protocol parent 1:0 prio 1 u32 match ip dport 23 0xffff flowid 1:1

这里为根队列1创建两个根类别,即1:1和1:2,其中1:1对应Telnet数据流,1:2对应80Mbit的数据流。然后,在1:2中,创建两个子类别1:21和1:22,分别对应WWW和E-mail数据流。由于类别1:21和1:22是类别1:2的子类别,因此他们可以共享分配的80Mbit带宽。同时,又确保当需要时,自己的带宽至少有40Mbit。

从这个例子可以看出,利用HTB中类别和子类别的包含关系,可以构建更加复杂的多层次类别树,从而实现的更加灵活的带宽共享和独占模式,达到企业级的带宽管理目的。

TC中的HTB队列简单创建与过滤相关推荐

  1. Linux内核TC工具链路带宽设计--HTB队列规定及简单的过滤器介绍

    1 HTB(Hierarchical Token Bucket, 分层的令牌桶) HTB 使用令牌和存储桶的概念,以及基于类的系统和过滤器,以允许对流量进行复杂和精细的控制.借助复杂的借用模型,HTB ...

  2. 使用TC的htb队列控制网络流量

    起因,放在公司内的部分服务器对外提供服务,而且是很重要的服务,但由于公司员工上网也要占据很大的流量,往往导致服务器抢不到带宽,严重影响服务器的对外服务,于是考虑限制公司员工上网的带宽,确保服务器对外提 ...

  3. JS 中对象的简单创建和继承

    对象的简单创建 1.通过对象直接量创建 比如 var obj = {}; 2.通过new 创建 比如 var obj = new Object(); // 相当于var obj = {}; var a ...

  4. python dataframe去掉索引_python中pandas.DataFrame的简单操作方法(创建、索引、增添与删除)...

    这篇文章主要介绍了python中pandas.DataFrame的简单操作方法,其中包括创建.索引.增添与删除等的相关资料,文中介绍的非常详细,需要的朋友可以参考借鉴,下面来一起看看吧. 前言 最近在 ...

  5. pandas 索引去重_python中pandas.DataFrame的简单操作方法(创建、索引、增添与删除) 如何更新pandas dataframe的值...

    我用Python做了一个樱花树,360说有活动感染病毒正...import random import turtle __Pen = turtle.Pen() # 分形樱花树 # "画你的e ...

  6. python删除列索引_python中pandas.DataFrame的简单操作方法(创建、索引、增添与删除)...

    前言 最近在网上搜了许多关于pandas.DataFrame的操作说明,都是一些基础的操作,但是这些操作组合起来还是比较费时间去正确操作DataFrame,花了我挺长时间去调整BUG的.我在这里做一些 ...

  7. linux HTB 队列限速

    原文链接: http://blog.chinaunix.net/uid-7530389-id-2050069.html 起因,放在公司内的部分服务器对外提供服务,而且是很重要的服务,但由于公司员工上网 ...

  8. 【Java 并发编程】线程池机制 ( 线程池执行任务细节分析 | 线程池执行 execute 源码分析 | 先创建核心线程 | 再放入阻塞队列 | 最后创建非核心线程 )

    文章目录 一.线程池执行任务细节分析 二.线程池执行 execute 源码分析 一.线程池执行任务细节分析 线程池执行细节分析 : 核心线程数 101010 , 最大小成熟 202020 , 非核心线 ...

  9. 在laravel5 中使用queue队列

    如何在laravel5 中使用queue队列 Laravel Queue是延迟处理应用程序中耗时任务的有效方法.此类任务的示例可能包括每当新用户在您的应用程序中注册或通过社交媒体分享帖子时发送验证电子 ...

  10. 死信队列和延迟队列_在实践中使用延迟队列

    死信队列和延迟队列 通常,在某些情况下,当您有某种工作或作业队列时,有必要不立即处理每个工作项或作业,而是要延迟一些时间. 例如,如果用户单击一个按钮来触发要完成的某项工作,而一秒钟后,用户意识到他/ ...

最新文章

  1. 微信支付报错:app没有获取微信支付权限
  2. 如何查看超大文本文件
  3. 7个重要内排序算法的实现以及实验比较
  4. SpringBoot图文教程4—SpringBoot 实现文件上传下载(亲测)
  5. hdu 1251 trie
  6. COGS 36. 求和问题
  7. GDB技巧:使用checkpoint解决难以复现的Bug
  8. SQL UNION 和 UNION ALL 操作符(mysql)
  9. jquery +做CheckBoxList全选,反选
  10. 转:基于TLS1.3的微信安全通信协议mmtls介绍
  11. Kubernetes-存活探针(liveness probe)(十六)
  12. 大数据之-Hadoop3.x_MapReduce_序列化案例FlowBean---大数据之hadoop3.x工作笔记0097
  13. 修改Ubuntu的键盘映射
  14. JAVA手机软件JAR和JAD文件内部文件详解
  15. tif软件Android版下载,TIF文件查看器
  16. [面试必考]OSI 网络七层协议以及各层的功能
  17. sublime 3207 激活
  18. 测试前的准备:搭建测试环境
  19. 怀旧服ouf头像插件_TukUI For 3.35 插件整合包 2019年怀旧服可用
  20. 打造数字化转型IT生态系统的IT管理方法:IT4IT一瞥

热门文章

  1. Hibernate - Query简易
  2. CentOS出错You don#39;t have permission to access on this server
  3. 利用Scrapy爬取拉勾网某职位信息
  4. Autodesk正在招聘Civil、Infraworks金牌支持工程师(Premium Support Specialist)
  5. 修改系统文件内容的经典错误总结
  6. eclipse jre 参数
  7. ios是否安装了某应用
  8. android开发歌词滑动效果_一些Flutter开发中的“坑”
  9. 集算器(仓库版)发布,黑科技获得用户好评
  10. Centos7.4源码搭建zabbix3.4.11企业级监控