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

文章摘自:http://www.php-oa.com/2009/06/23/linux_tc.html

 

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

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

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

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

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

  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(Traffic Control) 流量控制命令模拟网络延迟和丢包

    目录 TC案例 TC常用命令 TC安装 TC原理介绍 TC规则 TC操作原理 TC命名规则 TC单位 TC命令 TC案例 如何使用tc模拟网络延迟和丢包 修改网络延时:  sudo tc qdisc  ...

  7. 浅谈linux 下,利用Nginx服务器代理实现ajax跨域请求。

    ajax跨域请求对于前端开发者几乎在任何一个项目中都会用到,众所周知,跨域请求有三种方式: jsonp; XHR2 代理: jsonp: 这种应该是开发中是使用的最多的,最常见的跨域请求方法,其实aj ...

  8. Linux下四款Web服务器压力测试工具(http_load、webbench、ab、siege)介绍

    一.http_load程序非常小,解压后也不到100Khttp_load以并行复用的方式运行,用以测试web服务器的吞吐量与负载.但是它不同于大多数压力测试工具,它可以以一个单一的进程运行,一般不会把 ...

  9. Linux下几种并发服务器的实现模式

    Linux下的几种并发服务器的设计模式 1>单线程或者单进程 相当于短链接,当accept之后,就开始数据的接收和数据的发送,不接受新的连接,即一个server,一个client 不存在并发. ...

随机推荐

  1. windows 环境安装K8s

    文档地址: https://yq.aliyun.com/articles/508460?spm=a2c4e.11153940.blogcont221687.18.7dd57733hFolMo Dock ...

  2. 记录几个常用的Css样式效果

    1.更改字体,图标大小小于12px无效的问题 若我们设置font-size:10px是不会有效果的,需要使用 transform: scale(0.68); 更改字体最小大小 2.设置div边框虚化, ...

  3. sqlalchemy一对多的关系

    #encoding: utf-8 from sqlalchemy import create_engine,Column,Integer,String,Float,func,and_,or_,Text ...

  4. flask类装饰器

    from flask import Flask,request,views from functools import wraps app = Flask(__name__) #自定义登录装饰器 de ...

  5. 接口自动化框架 - httprunner

    自己曾经写过一个接口自动化的框架,并做了一版本的优化,一直觉得做的还不错,且没依赖现有的框架. 最近因为一些工作的原因,开始又思考之前写的框架的一些缺点及如何优化,所以找到比较有名的httprunne ...

  6. SVN随笔记录(二)

    二.TortoiseSVN操作 1.下载,安装,过程中需要勾选x ,目的是为了后期绑定idea 2.如果点击后出现一系列的找不到目标文件提示,重启电脑 3.重启后,绑定仓库路径 4.一般情况输入账号密 ...

  7. 关于前端JS判断字符串是否包含另外一个字符串的方法总结

    RegExp 对象方法 test() var str = "abcd"; var reg = RegExp(/d/); console.log(reg.test(str)); // ...

  8. Kinect开发-开发环境搭建

    0.安装Visual Studio.版本无所谓,但Kinect SDK for Windows只支持C/C#.接下来的开发语言将使用C#,用户界面框架使用WPF. 安装Kinect SDK for W ...

  9. mweb发布文章为什么默认TinyMCE编辑器?

    如果是通过 metaweblog api 发布的,需要在网站分类中添加 [Markdown] 标记

  10. 移除django的旧版本

    移除django的旧版本 下面这一段代码打进去绝对能看到你想要的,根据这个路径去找版本文件夹,他的名字应该是django.2xx.xxx很长一段,请你删了它! import django import ...