tc 介绍

在linux中,tc 有二种控制方法 CBQ 和 HTB.HTB 是设计用来替换 CBQ 的.HTB比CBQ更加灵活,但是CPU
开销也更大,通常高速的链路会使用CBQ,一般而言HTB使用的更加广泛。HTB  的规则本质上是一个树形结构,包括三个基本的构成块:队列规定
qdisc(queueing discipline) ,类(class)和分类器(Classifiers).

qdisc
队列规则(queueing discipline):

用来实现控制网络的收发速度.通过队列,linux可以将网络数据包缓存起来,然后根据用户的设置,在尽量不中断连接(如
tcp)的前提下来平滑网络流量.需要注意的是,linux 对接收队列的控制不够好,所以我们一般只用发送队列,即"控发不控收".它封装了其他两个主要 tc
组件(类和分类器).内核如果需要通过某个网络接口发送数据包,它都需要按照为这个接口配置的 qdisc 队列规则把数据包加入队列.然后,内核会尽可能多地从
qdisc里面取出数据包,把它们交给网络适配器驱动模块.

最简单的 QDisc 是 pfifo
它不对进入的数据包做任何的处理,数据包采用先入先出的方式通过队列.不过,它会保存网络接口一时无法处理的数据包.常有的队列规则包括 FIFO 先进先出,RED
随机早期探测,SFQ 随机公平队列和令牌桶 Token Bucket,类基队列 CBQ,CBQ 是一种超级队列,即它能够包含其它队列,甚至其它
CBQ.

Class 类

class
用来表示控制策略.很显然,很多时候,我们很可能要对不同的IP实行不同的流量控制策略,这时候我们就得用不同的class来表示不同的控制策略了.

Filter
规则

filter 用来将用户划入到具体的控制策略中(即不同的 class
中).比如,现在,我们想对xxa,xxb两个IP实行不同的控制策略(A,B),这时,我们可用 filter 将 xxa 划入到控制策略 A,将 xxb
划入到控制策略 B,filter 划分的标志位可用 u32 打标功能或 IPtables 的 set-mark (大多使用iptables
来做标记)功能来实现.
       目前,tc可以使用的过滤器有:fwmark分类器,u32 分类器,基于路由的分类器和 RSVP
分类器(分别用于IPV6、IPV4)等;其中,fwmark 分类器允许我们使用 Linux netfilter 代码选择流量,而 u32 分类器允许我们选择基于
ANY 头的流量 .需要注意的是,filter (过滤器)是在QDisc 内部,它们不能作为主体.

tc 的应用流程

如果将HTB的分层结构看作树,那么每个节点就被称为一个 class,每个class可以设置一个 qdisc,默认的是 tc-pfifo.
另外HTB还可以设置一些过滤器,通过这些过滤器可以将到来的包分发到指定的 class 上。这里过滤器通常挂载在 root
节点(eth0接口),但匹配只能匹配叶子节点。
        
数据包->iptables(在通过iptables时,iptables根据不同的ip来设置不同的mark)->tc(class)->tc(queue)

应用
假设 eth0 位是服务器的外网网络接口.开始之前,先要清除 eth0所有队列规则

tc qdisc
del dev eth0 root 2> /dev/null > /dev/null

1) 定义最顶层(根)队列规则,并指定 default 类别编号

tc qdisc add dev eth0 root handle 1: htb
default 2

2) 定义第一层的 1:1 类别 (速度)
本来是要多定义第二层叶类别,但目前来看,这个应用中就可以了.

tc class add dev
eth0 parent 1:1 classid 1:2 htb rate 98mbit ceil 100mbit prio 2
tc class add
dev eth0 parent 1:1 classid 1:3 htb rate 1mbit ceil 2mbit prio 2

注:以上就是我们控制输出服务器的速度,一个为98M,一个为 2M.
rate:
是一个类保证得到的带宽值.如果有不只一个类,请保证所有子类总和是小于或等于父类.
prio:用来指示借用带宽时的竞争力,prio越小,优先级越高,竞争力越强.
ceil:
ceil是一个类最大能得到的带宽值.

同时为了不使一个会话永占带宽,添加随即公平队列sfq.

tc qdisc add dev eth0 parent 1:2 handle 2: sfq
perturb 10
tc qdisc add dev eth0 parent 1:3 handle 3: sfq perturb 10

3) 设定过滤器
过滤器可以使用本身的 u32 也可以使用 iptables 来打上标记
指定在root 类 1:0 中,对
192..168.0.2 的过滤,使用 1:2 的规则,来给他 98M 的速度,写法就如下

tc filter add dev eth0 protocol
ip parent 1:0 u32 match ip src 192.168.0.2 flowid 1:2
tc filter add dev eth0
protocol ip parent 1:0 u32 match ip src 192.168.0.1 flowid 1:3

如果是所有 ip 写法就如:

tc filter add dev eth0 protocol ip parent 1: prio 50 u32 match ip dst
0.0.0.0/0 flowid 1:10

使用 iptables 来配合过滤器
还可以使用这个方法,但需要借助下面的 iptables 的命令来做标记了

tc filter add
dev eth0 parent 1: protocol ip prio 1 handle 2 fw flowid 1:2
tc filter add
dev eth0 parent 1: protocol ip prio 1 handle 2 fw flowid 1:3

iptables 只要打上记号就行了,这种时候大多用在做网关的时候,很合适使用这种方法.

iptables -t mangle -A
POSTROUTING -d 192.168.0.2 -j MARK --set-mark 10
iptables -t mangle -A
POSTROUTING -d 192.168.0.3 -j MARK --set-mark 20

tc对高速度的控制
Rate ceiling 速率限度
      
参数ceil指定了一个类可以用的最大带宽, 用来限制类可以借用多少带宽.缺省的ceil是和速率一样,这个特性对于ISP是很有用的,
因为他们一般限制被服务的用户的总量即使其他用户没有请求服务.(ISPS 很想用户付更多的钱得到更好的服务) ,注根类是不允许被借用的,
所以没有指定ceil。
注: ceil的数值应该至少和它所在的类的速率一样高, 也就是说ceil应该至少和它的任何一个子类一样高

Burst 突发
       网络硬件只能在一个时间发送一个包这仅仅取决于一个硬件的速率.
链路共享软件可以利用这个能力动态产生多个连接运行在不同的速度. 所以速率和ceil不是一个即时度量只是一个在一个时间里发送包的平均值.
实际的情况是怎样使一个流量很小的类在某个时间类以最大的速率提供给其他类. burst 和cburst
参数控制多少数据可以以硬件最大的速度不费力的发送给需要的其他类.
       如果cburst 小于一个理论上的数据包他形成的突发不会超过ceil
速率, 同样的方法TBF的最高速率也是这样.
       你可能会问, 为什么需要bursts . 因为它可以很容易的提高向应速度在一个很拥挤的链路上.
比如WWW 流量是突发的. 你访问主页. 突发的获得并阅读. 在空闲的时间burst将再"charge"一次.
注: burst
和cburst至少要和其子类的值一样大.

tc命令格式:
tc qdisc [ add | change | replace | link ] dev
DEV [ parent qdisc-id | root ] [ handle qdisc-id ] qdisc [ qdisc specific
parameters ]

tc qdisc ... dev dev ( parent classid | root) [ handle major: ]
htb [ default minor-id ]

Qdisc的参数:  

parent major:minor 或者 root
一个qdisc是根节点就是root,否则其他的情况指定parent。其中major:minor是class的handle
id,每个class都要指定一个id用于标识。

handle major:
,这个语法有点奇怪,是可选的,如果qdisc下面还要分类(多个class),则需要指定这个hanlde。对于root,通常是"1:"。

注意:对于tc命令中的qdiscs和classes,标识handle(classid)的语法都是x:y,其中x是一个整数用来标识一个
qdisc,y是一个整数,用来标识属于该qdisc的class。qdisc的handle的y值必须是0,class的handle的y值必须是非
0。通常"1:0"简写为"1:",也就是上面看到的写法。

default minor-id,未分类(不能和filter匹配)的流量(默认的)会被送到这个minor所指定的类(class
id为major:minor-id)。

tc class ... dev dev parent major:[minor] [ classid
major:minor ] htb rate rate [ ceil rate ] burst bytes [ cburst bytes ] [ prio
priority ]

Class的参数:

parent
major:minor
,指定这个类的父节点,父节点可以是Qdisc,也可以是Class,如果是Qdisc,那么就不用指定minor,这个是必须的参数。

classid
major:minor
,classid作为class的标识,这个是可选的。如果这个class没有子节点,就可以不指定。major是父qdisc的handle。

prio 低优先级的class会优先匹配  

rate 这个class和其所有子类的速率

ceil 如果父类有空余带宽,最高可以分配给当前class的值,默认是和rate一样。

burst 允许以ceil的速率发送的字节数,应该至少和子类的burst最大值一样。  

cburst
允许以网口的最高速率发送的字节数,应该至少和子类的cburst最大值一样。功能类似tbf中的peakrate,当这个值限制很小时,可以避免突发的流量,以避免瞬间速率超过ceil。

quantum 每轮当前的class能发送的字节数,默认的计算quantum = rate / r2q.  Quantum必须大于1500 小于
60000。quantum只在class的流量超过了rate但是没超过ceil时使用。quantum越小,带宽共享的效果就越好。  r2q
用来计算quantum,r2q默认是10。

tc filter [ add | change | replace ] dev DEV [ parent qdisc-id | root ]
protocol protocol prio priority filtertype [ filtertype specific parameters ]
flowid flow-id

显示
tc [-s | -d ] qdisc show [ dev DEV ]
tc [-s | -d ] class show dev
DEV tc filter show dev DEV

查看tc的状态
tc -s -d qdisc show dev eth0
tc -s -d class show dev eth0

删除tc规则

tc qdisc del dev eth0 root

实例

使用 tc 对单个IP 进行速度控制

tc qdisc add dev eth0 root handle 1:
htb r2q 1
tc class add dev eth0 parent 1: classid 1:1 htb rate 30mbit ceil
60mbit
tc filter add dev eth0 parent 1: protocol ip prio 16 u32 match ip dst
192.168.1.2 flowid 1:1

就可以限制192.168.1.2的下载速度为30Mbit最高可以60Mbit ,其中
r2q,是指没有default的root,使整个网络的带宽没有限制

使用 tc 对整段 IP 进行速度控制

tc qdisc add dev eth0 root handle 1:
htb r2q 1
tc class add dev eth0 parent 1: classid 1:1 htb rate 50mbit ceil
1000mbit
tc filter add dev eth0 parent 1: protocol ip prio 16 u32 match ip
dst 192.168.111.0/24 flowid 1:1

就可以限制192.168.111.0 到255
的带宽为3000k了,实际下载速度为200k左右.
这种情况下,这个网段所有机器共享这200k的带宽.
还可以加入一个sfq(随机公平队列)

tc
qdisc add dev eth0 root handle 1: htb r2q 1
tc class add dev eth0 parent 1:
classid 1:1 htb rate 3000kbit burst 10k
tc qdisc add dev eth0 parent 1:1
handle 10: sfq perturb 10
tc filter add dev eth0 parent 1: protocol ip prio
16 u32 match ip dst 192.168.111.168 flowid 1:1

sfq,他可以防止一个段内的一个ip占用整个带宽.

使用 tc 控制服务器对外的速度为 10M

如下,我要管理一台服务器,只能向外发 10M 的数据

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
100mbit ceil 100mbit
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
tc
filter add dev eth0 protocol ip parent 1: prio 2 u32 match ip dst
220.181.xxx.xx/32 flowid 1:1 # 上面这台,让 220.181.xxx.xx/32 这台跑默认的,主要是为了让这个 ip
连接进来不被控制
tc filter add dev eth0 protocol ip parent 1: prio 50 u32 match ip
dst 0.0.0.0/0 flowid 1:10 # 默认让所有的流量都从这个通过

参考:http://blog.chinaunix.net/u3/94771/showart_1906064.html

http://liuleijsjx.javaeye.com/blog/402152

【转载】linux下使用 TC 对服务器进行流量控制的更多相关文章

  1. linux下使用 TC 对服务器进行流量控制

    tc 介绍 在linux中,tc 有二种控制方法 CBQ 和 HTB.HTB 是设计用来替换 CBQ 的.HTB比CBQ更加灵活,但是CPU 开销也更大,通常高速的链路会使用CBQ,一般而言HTB使用 ...

  2. [转载]Linux下非root用户如何安装软件

    [转载]Linux下非root用户如何安装软件 来源:https://tlanyan.me/work-with-linux-without-root-permission/ 这是本人遇到的实际问题,之 ...

  3. Linux下配置一个VNC服务器

    在Linux下配置一个VNC服务器,并设置2个用户,要求其中一个用户登录时不需要输入密码. 然后在客户端使用ssh+vncview的方式访问. 1确认vnc安装 2配置vncserver 3测试vnc ...

  4. linux下搭建svn本地服务器

    在linux下搭建svn本地服务器可以很好的管理自己的代码,具体过程如下: # mkdir svn_local # cd svn_local  # svnadmin create led_diplay ...

  5. linux下安装配置svn服务器

    linux下安装配置svn服务器 1. svn服务器安装 将subversion-1.4.0.tar.gz和subversion-deps-1.4.0.tar.gz传到服务器. tar xfvz su ...

  6. linux 下使用 tc 模拟网络延迟和丢包-使用 linux 模拟广域网延迟 - Emulating wide area network delays with Linux

    tc 是linux 内置的命令:使用man pages 查看 我们看到,其功能为 show / manipulate traffic control settings,可对操作系统进行流量控制: ne ...

  7. 转载-Linux下搭建VPN服务器(CentOS、pptp)

    转自:http://www.cnblogs.com/sixiweb/archive/2012/11/20/2778732.html 搭建过程参考这篇文章 先说我搭建过程中出现的问题吧: 按照 教程搭建 ...

  8. [转载]linux下svn常用指令

    一下内容转载于:http://blog.chinaunix.net/space.php?uid=22976768&do=blog&id=1640924.这个总结的很好~ windows ...

  9. 转载Linux下开启MySQL日志

    转载https://blog.csdn.net/weixin_38187469/article/details/79273962 开启mysql日志   1.查看日志是否启用 mysql> sh ...

随机推荐

  1. ps -aux --sort -rss |head 列出进程拿物理内存占用排序 使用ps aux 查看系统进程时,第六列即 RSS列显示的就是进程使用的物理内存。

    ps -a     Select all processes -u userlist               Select by effective user ID (EUID) or name. ...

  2. android studio中如何替换gradle以防下载卡住

    我们在开发过程中需要导入别人的demo工程,那么你有事就会下载gradle构建文件,然而有时下载会一直卡住,那么这时候你就会想,我自己用迅雷去下载gradle文件然后不就行了,然后问题就来了 1.我们 ...

  3. [已解决]window下Can't connect to MySQL server on 'localhost' (10061)与无法启动MYSQL服务”1067 进程意外终止”

    查了一圈,发现都解决不了我的问题,查了 window 系统日志,提示缺少了某些文件,文件怎么丢的我也不知道,以下是解决办法. -- 我的 mysql 版本为 5.6.x 压缩包版本,我的 mysql ...

  4. 怎么获取Android应用程序的上下文

    在一个应用里面,有很多activity,而这些activity之间经常要进行互相启动.往复跳转.还有就是通过Notification启动.当activity多了之后,如果设置他的模式为单例模式,或者不 ...

  5. Distinct powers (Project Euler 29 加强版)

    题目大意: $2<=a,b<=n$ 求 $a^b$能表示多少不同的正整数. 原题中n=100,可以直接暴力求解,常见的两种解法是写高精度或者取对数判断相等. 直觉告诉我应该有更加优秀的解法 ...

  6. 福昕阅读器打开PDF文档速度慢

    RT---------------- 操作如下两步可加快打开速度: 1.Program Files\Foxit Software\Foxit Reader下面的Shell Extensions文件夹删 ...

  7. 事务处理笔记《一》ADO.NET级别的事务

    现在我们对事务的概念和原理都有所了解了,并且作为已经有一些基础的C#开发者,我们已经熟知编写数据库交互程序的一些要点,即: (1)使用SqlConnection类的对象的Open()方法建立与数据库服 ...

  8. 详解Amazon S3上传/下载数据

    AWS简单储存服务(Amazon S3)是非常坚牢的存储服务,拥有99.999999999%的耐久性(记住11个9的耐久性). 使用CloudBerry Explorer,从Amazon S3下载数据 ...

  9. SpringBoot整合Dubbo报错: java.lang.ClassCastException

    com.alibaba.dubbo.rpc.RpcException: Failed to invoke remote proxy method queryGoodsLimitPage to regi ...

  10. 数组中binarySearch 中小小的误区! 用的时候大家要注意点