tc 的使用

TC

tc 是 linux 中常用的流控软件,但是 tc 命令中的各种规则和概念乍一看让人望而生畏,其实 tc 并没有看起来那样复杂。tc 主要针对流量的控制和对流的整理。这里的流主要指的是传输层 tcp/udp 协议中的连接,视从 A 主机端口号到 B 主机端口号的网络传输是一条流。一台主机会有很多这样的流,我们有时候想让一些流的优先级高一些,即将属于该流的数据包优先发送。但是一个网卡在同一时刻内只能发送一个数据包,多个流的数据包只能排着队发送,这样就引出了网卡发送队列,以及如何排队等问题。

TC 的队列

TC 的队列分为两种,一种是无类队列,一种是有类队列。

  • 无类队列,不能派生子类
  • 有类队列,可以派生子类,其使用过程一般来说是,先设置网卡队列,然后设置根类队列,然后从根类队列中引申出各种子类规则,子类规则也可以再派生;再就是生成过滤器,过滤器有不同的过滤方法和参数,过滤器和对应的子类绑定;最后是设置将过滤器和路由绑定(当然可以不用路由来过滤,还有很多其他过滤方式,但是本文只针对路由),这样之前的队列规则就在该条路由上的数据包起作用了。
为何排队规则就可以限制流量了呢?

以最经典的案例 tbf(全称令牌桶队列),首先解释一下令牌,数据包生成后,都是先存放在缓冲队列中,当决定是否发送一个数据包的时候,首先看一下当前否有令牌,如果有的话,那就通过网卡发送一个数据包,同时该令牌就无效了。令牌由系统定时发送给网卡,而发送的时间间隔就会间接控制了带宽,这是为何呢?数据包大小相对固定,控制了发送时间间隔,就相当于控制了单位时间内发送的数据量,也就是说相当于控制了带宽。

TC 实战

“我只是想找个控制流量的方法哎,我不想当运维大佬啊!!!”

这里跳过对各种队列的特性的简介,因为如果只是想简单地控制一下某个应用的流量,实际上并不需要了解那么多,知晓 tbf,最多再了解一下可生成子类的 htb 即可。回忆当初,我只想控制一下流量,结果在网上找到的资料,大部分都是先闷头来一顿长篇累牍地各种队列的特点的介绍,大部分初学者面对这些东西都会一头雾水,直接就是劝退。

当然如果在 linux 环境下用 man tc 命令看一下 tc 的使用手册,如果看起来毫无压力,那就没有必要看后面的内容了。

TC 基本命令

首先先看一条最简单的命令
tc qdisc add dev ens33 root tbf rate 1mbit limit 9kbit buffer 1600

  • tc,表示命令 tc
  • qdisc, 表示队列相关的命令
  • add,表示添加一条队列规则,相似的命令还有 delete,change,大家应该就见文知意了
  • dev,表示后面跟着的是网卡名,想看一下
  • ens33,电脑的网卡
  • root,表示根节点
  • tbf,表示队列类型,这里是 tbf 队列,tbf 的特点是不会有分类
  • rate,limit,buffer,这些都是 tbf 队列相关的参数,不同类型的队列参数不同。

所以,上面这条命令的含义是什么呢?这条命令在网卡上定义了一个 tbf 队列,限流为 1mbit/s,也就是 125kb/s。

验证试验命令结果——iperf

经常用 iperf 命令来测量带宽,iperf 有很多参数,比如可以指定 tcp 还是 udp。如果 tc 没有指定限制的是 tcp 还是 udp,默认是限制在 ip 层上,测量的时候推荐使用 iperf 的 udp 模式来测量带宽。实践证明 iperf 用 tcp 测试的时候会不准确,我猜测是 tcp 在传输数据会先创建连接,如果创建连接失败,这些创建连接而发送的这些数据包却不会被记录到流量统计中,这就造成了统计结果不准确。

TC 控制丢包时延等参数

tc 除了有流量控制之外,还有对丢包和时延的控制,而这个的主要实现方式是提供了 netem 这个队列类型。一条典型的限制丢包和时延的命令如下所示:
tc qdisc add dev ens33 root netem loss 10% delay 1ms
命令简单易懂,就是在网卡 ens33 的队列根节点上加了 netem 这个队列,其中这个队列的丢包率为 10%,时延为 1ms。netem 队列还支持丢包和时延的概率分布。

验证试验命令结果——ping

随便 ping 一个会流经对应网卡的 ip 地址,可以根据返回的 ICMP 包来观察丢包率和时延,借此来确认自己设置的规则是否起效。

既控制丢包又控制带宽

工作中很多场景是要求我们既控制丢包时延又控制带宽的,这给怎么办呢?用下面两条命令来实现。
tc qdisc add dev ens33 root handle 1:0 netem loss 100ms
tc qdisc add dev ens33 parent 1:1 handle 10: tbf rate 256kbit buffer 1600 limit 3000

第一条命令表示设置了 netem 队列,第二条命令表示 tbf 队列继承了 netem 队列。想既限制带宽又限制时延丢包,只能是让 tbf 继承 netem,而不能反过来,这是由两种队列的特性决定的,netem 不能继承任何队列, tbf 不能派生任何队列。

这命令的结果就是实际的网络带宽会变成 丢包率 * tbf 设置带宽

删除某个网卡上所有策略

不再使用策略了的时候,就可以使用一下命令删除,这条命令实际上是删除了 root 节点下的所有策略。
tc qdisc delete dev ens33 root

查看网卡被设置的 tc 策略

tc qdisc show dev ens33

进阶之,控制单条路由的带宽

tc 还可以精准地控制某条路由甚至是某些路由的带宽丢包之类的,不过这就要借助子类来实现了。
待续…

进阶之,控制下行的带宽

tc 默认是控制上行的带宽的,也就是出口带宽,没有直接控制入口带宽的方式。但是 tc 提供了一种曲线通幽的实现方式 —— ingress 队列,该队列中存储了网卡入口的数据包,我们可以将 ingress 队列中的数据包转发到一个虚拟网卡上,现在相对于虚拟网卡来说,数据包的流向又可以看成是上行的,我们可以在虚拟网卡上做之前提到的规则控制,定义各种各样的队列。

linux 经常使用的虚拟网卡为 ifb,该网卡是需要安装到内核中的。

总结

tc 是一个非常强大的工具,同时很灵活,用路由器 + tc 可以代替一个专业的网络损伤仪呢。

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值