专栏首页CU技术社区Linux 流量控制全攻略?看这里~

Linux 流量控制全攻略?看这里~

WebjxCom 友情提示: 公司一台服务器,网络环境太高,那台服务器和源服务器连接下载,就跑到 400M-500M,为了控制一下,所以研究了一下 TC. 来做流量控制。给他控制到小点,不要让这一台占了所有的网络。TC 很是强大啊,很多所谓的硬件路由器,都是基于这个做的。

TC 介绍

在 linux 中,TC 有二种控制方法 CBQ 和 HTB.HTB 是设计用来替换 CBQ 的。它是一个层次式的过滤框架。

TC 包括三个基本的构成块: 队列规定 qdisc(queueing discipline)、类 (class) 和分类器 (Classifiers)

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

最简单的 QDisc 是 pfifo 它不对进入的数据包做任何的处理,数据包采用先入先出的方式通过队列。不过,它会保存网络接口一时无法处理的数据包。

队列规则包括 FIFO(先进先出),RED(随机早期探测),SFQ(随机公平队列) 和令牌桶 (Token Bucket),类基队列 (CBQ),CBQ 是一种超级队列,即它能够包含其它队列 (甚至其它 CBQ)。

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

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 内部,它们不能作为主体。

数据包 ->iptables(在通过 iptables 时,iptables 根据不同的 ip 来设置不同的 mark)->TC(class)->TC(queue)

应用

假设 eth0 位是服务器的外网网络接口。

1) 首先在 eth0 的 qdiscA,qdiscA 控制通过本机到外网的速度,因此是用来控制服务器流出速度的

#tc qdisc add dev eth1 root handle 1:htb default 1

添加设置接口 最上层 句柄 (做标记用) 标记 默认使用 1 的 class

解释如下:无论是队列,还是 class 和 filter 都有 ID 之类的标志符,一般都有 parent(父,上层的),注意 ID 具有接口本地性,不同的网络接口可以有相同的 ID. 对于这里因为 qdisc 在顶部,所以 parent 无,用‘root’字样来标识,ID 用 1:来标志

default 91′表示当某个 ip 流不满足任何已设定的 filter 规则时,将自动归入 class 1 中。更详细的指令规则说明请参考手册。

2) 然后在 qdisc 下建立两个 class,来指定 eth0 控制通过本机到外网的速度

#tc class add dev eth0 parent 1:0 classid1:30 htb rate 2mbit ceil 4mbit prio 2

注:以上就是我们控制输出服务器的速度,为 2M,最大可以到 4M

rate: 是一个类保证得到的带宽值。如果有不只一个类,请保证所有子类总和是小于或等于父类。

prio:用来指示借用带宽时的竞争力,prio 越小,优先级越高,竞争力越强。

ceil: ceil 是一个类最大能得到的带宽值。 

3) 接着针对不同的应用在各 root class 下设置不同的类,。示例如下。(如果只有一个类,这个就没有必要了)

#tc class add dev eth0 parent 1:30 classid 1:31 htbrate 0.5mbit ceil 2mbit prio 3

同时为了不使一个会话永占带宽,在节点 (即本文的各应用结点) 添加随即公平队列 sfq.(多 IP)

#tc qdisc add dev eth0 parent 1:31 handle 31:sfq perturb 10

4) 接着添加过滤器。

#tc filter add dev eth0 parent 1: protocol ipprio 31 handle 31 fw flowid 1:31

5) 用 iptable 打标,也可以使用 u32 之类

#iptables -t mangle -I FORWARD -i !eth1 -p tcp –sport 80 -s xxx.xxx.xxx.xxx –j MARK –set-mark 31

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 class [add | change | replace] dev DEV parent qdisc-id [ classid class-id ] qdisc [ qdisc specific parameters ]
  
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

实例:

下载
  
下载限制单个 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,使整个网络的带宽没有限制
  
下载整段 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 占用整个带宽。

本文分享自微信公众号 - CU技术社区(ChinaUnix2013)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-10-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 各种页的意义

    内存回收,也就是系统释放掉可以回收的内存,比如缓存和缓冲区,就属于可回收内存。它们在内存管理中,通常被叫做文件页(File-backed Page)。大部分文件...

    233333
  • 一篇文章教你读懂UI绘制流程我的Android重构之旅:框架篇

    在我们开发的初期往往并不需要什么框架,因为 Android Framework 良好的容错性帮助我们避免了很多问题,甚至你不需要深入的学习就可以写出一个较为完善...

    Android技术干货分享
  • linux内核的冷热页分配器

    先说说cpu的cache,和cpu的cache比起来访问主内存是非常慢的,为了加快速度根据本地性原则,cpu在访问主内存的时候会把附近的一块数据都加载到cpu的...

    233333
  • Linux下经常使用的C/C++开源Socket库【转】

    转自:https://www.cnblogs.com/gccbuaa/p/7015599.html

    用户3033338
  • Linux-3.14.12内存管理笔记【构建内存管理框架(1)】

    传统的计算机结构中,整个物理内存都是一条线上的,CPU访问整个内存空间所需要的时间都是相同的。这种内存结构被称之为UMA(Uniform Memory Arch...

    233333
  • Linux-3.14.12内存管理笔记【伙伴管理算法(2)】

    具体的算法初始化则回到start_kernel()函数接着往下走,下一个函数是mm_init():

    233333
  • Linux用户的福音,记忆力解放!快速调用复杂命令...

    但是,命令的帮助文档往往内容太太太太多了,在里面找到自己关心的部分实在太难了。查找出来的方法也不能直接使用,还需要手动粘贴下来。

    昱良
  • Linux-3.14.12内存管理笔记【构建内存管理框架(4)】

    虽说前文分析内存管理框架构建的实现,提到了find_zone_movable_pfns_for_nodes(),但这里不准备复述什么,仅针对required_m...

    233333
  • Linux下经常使用的C/C++开源Socket库

    1. Linux Socket Programming In C++ : http://tldp.org/LDP/LG/issue74/tougher...

    用户3033338
  • 【Linux】聊聊Linux文件管理那些事

    //在Centos7之前,bin目录和sbin目录直接存放于根目录中,Centos7就移动到了usr目录中了,同样tmp目录也从usr移动到了var目录中去。

    一名白帽的成长史

扫码关注云+社区

领取腾讯云代金券