linux 包含复杂的带宽管理系统 tc (流量控制,traffic control)。该系统支持分
类、优先、共享和输入、输出流量限制等。这套系统可以与专用的带宽管理系统相媲美。
1. 基本的构成块
tc 包括三个基本的构成块:
队列规定(queueing discipline )、类(class)和分类器(classifiers)
队列规定可以看作设备的流量/数据包管理器。
队列规定内封装了其他两个主要tc组件(类和分类器),控制数据的流动。
目前,有一些设备队列规定可以用来管理设备,包括类基队列(cbq),优先级和csz
(clark-shenker-zhang)等。cbq 是一种超级队列,即它能够包含其它队列(甚至其它cbq)。
类由设备队列规定来管理。类由若干规则(rule)构成,这些规则用以管理那个类所拥有
的数据。例如,某类里的全部数据包都受到 1 mbps的速率限度,而在午夜和早上6点的一
段时间段内允许最高达 3 mbps。
一些队列规定可以绑定到类上,包括fifo(先进先出),red(随机早期探测),sfq(随
机公平队列)和令牌桶(token bucket)。
如果设备上未绑定队列规定,则使用基本的fifo。
另外, cbq,csz和优先级也能用于类,以及类的子类。这表明使用tc,可以轻松地建造
非常复杂的流量控制。管理类的队列规定可以称为类队列规定(class queueing disciplines)。
一般地,类队列规定管理该类的数据和队列,能决定延迟、丢掉或者重新分类它管理的包。
分类器或过滤器描述包,并且把他们映射到队列规定所管理的类。
这些过滤器通常都提供简单的描述语言,指定选择包、把包映射到类的方法。
目前,tc可以使用的过滤器有:fwmark分类器,u32分类器,基于路由的分类器和rsvp分
类器(分别用于ipv6、ipv4)等;其中,fwmark分类器允许我们使用 linux.netfilter
代码选择流量,而u32分类器允许我们选择基于 any 头的流量 。所有的防火墙过滤器,
例如,ipchains,都能用来分类包。
tc代码位于内核,不同的功能块既能编译为模块,也能直接编进内核。
与内核代码或模块的通信和配置由用户级程序tc完成。
2. 示例
2.1 编译内核
首先要确保选中 kernel/user.netlink socket,因为只有这样 tc 才能通过.netlink
与内核通讯。
然后,把队列规定和分类器都编进内核。这其中包括:
qos or fair queueing, cbq packet scheduler, csz packet scheduler, the
simplest prio pseudoscheduler, red queue, sfq queue, tbf queue, qos
support, rate estimator, packet classifier api, routing-tables-based
classifier, u32 classifier, special rsvp classifier 和 special rsvp
classifier for ipv6。
然后就是大家熟知的编译和安装过程了。
2.2 建立
[因特网] ---〈e3、t3 等〉--- [linux 路由器] --- [office+isp]
eth1 eth0
上图中的 linux 路由器有两个接口,不妨称之为 eth0 和 eth1。eth1 连接到路由器,
eth0 连接到包括公司防火墙在内的子网上。
由于我们只能限制发送的内容,所以我们需要两套独立的、但可能非常相似的规则集。我
们可以通过改变发送次序来控制传输速率。通过修改 eth0 上的队列,我们可以确定客户
的下载(download)速率;通过修改 eth1 上的队列,我们可以确定我们公司自己的用
户的上载(upload)速率。
比如说,公司连接到因特网的线路带宽为 10 兆,同时满足外部客户和公司自己用户的需
要;此时,我们就需要一种策略,来进行管理和协调。cbq 就可以满足我们的要求。
我们有两个主类:'isp' 和 'office'。我们可以决定,客户有 8 兆的带宽,office
用户有 2 兆的带宽。
我们首先发布如下的命令:
# tc qdisc add dev eth0 root handle 10: cbq bandwidth 10mbit avpkt 1000
其含义是:我们配置了 eth0 的队列规定,root 表示这是根(root)规定,其句柄
(handle)设定为 10:'。
其类型为 cbq。带宽为 10 m,平均包大小为 1000 字节。
下面生成根类(root class):
# tc class add dev eth0 parent 10:0 classid 10:1 cbq bandwidth 10mbit rate \
10mbit allot 1514 weight 1mbit prio 8 maxburst 20 avpkt 1000
这条命令其实不比前一条命令有更多的含义。其中,1514 是 mtu 的值。
下面生成 isp 类:
# tc class add dev eth0 parent 10:1 classid 10:100 cbq bandwidth 10mbit rate \
8mbit allot 1514 weight 800kbit prio 5 maxburst 20 avpkt 1000 \
bounded
我们分配了 8 兆的带宽给它,其中 bounded 表示该类不能超过该阀值。
下面生成 office 类:
# tc class add dev eth0 parent 10:1 classid 10:200 cbq bandwidth 10mbit
rate \
2mbit allot 1514 weight 200kbit prio 5 maxburst 20 avpkt 1000 \
bounded
为了更清晰起见,我们的类可以用下图表示:
+-------------[10: 10mbit]-------------------------+
+-------------[10:1 root 10mbit]-----------------+
+-----[10:100 8mbit]---------+ [10:200 2mbit]
isp office
+----------------------------+ +------------+
+------------------------------------------------+
+--------------------------------------------------+
我们已经向内核通知了我们的类,我们还需要告诉内核如何管理队列,如下所示:
# tc qdisc add dev eth0 parent 10:100 sfq quantum 1514b perturb 15
# tc qdisc add dev eth0 parent 10:200 sfq quantum 1514b perturb 15
这里,我们使用了随机公平队列(sfq),在消耗 cpu 周期较少的情况下,其性能还是可
以接受的。其它一些队列规定可能更好,但要占用较多的 cpu 资源。令牌桶过滤器也经
常使用。
下面还有一件事要作:告诉内核网络包和类的映射关系。
# tc filter add dev eth0 parent 10:0 protocol ip prio 100 u32 match ip dst \
150.151.23.24 flowid 10:200
# tc filter add dev eth0 parent 10:0 protocol ip prio 25 u32 match ip dst \
150.151.0.0/16 flowid 10:100
这里,我们假定 office 位于防火墙 150.151.23.24 的后面,其它 ip 地址都属于
isp。
u32 匹配是一种比较简单的匹配,我们可以使用.netfilter 生成更加复杂的匹配规则。
我们已经分配了下载带宽,下面是上载带宽的分配:
# tc qdisc add dev eth1 root handle 20: cbq bandwidth 10mbit avpkt 1000
# tc class add dev eth1 parent 20:0 classid 20:1 cbq bandwidth 10mbit rate \
10mbit allot 1514 weight 1mbit prio 8 maxburst 20 avpkt 1000
# tc class add dev eth1 parent 20:1 classid 20:100 cbq bandwidth 10mbit rate \
8mbit allot 1514 weight 800kbit prio 5 maxburst 20 avpkt 1000 \
bounded
# tc class add dev eth1 parent 20:1 classid 20:200 cbq bandwidth 10mbit rate \
2mbit allot 1514 weight 200kbit prio 5 maxburst 20 avpkt 1000 \
bounded
# tc qdisc add dev eth1 parent 20:100 sfq quantum 1514b perturb 15
# tc qdisc add dev eth1 parent 20:200 sfq quantum 1514b perturb 15
# tc filter add dev eth1 parent 20:0 protocol ip prio 100 u32 match ip src \
150.151.23.24 flowid 20:200
# tc filter add dev eth1 parent 20:0 protocol ip prio 25 u32 match ip src \
150.151.0.0/16 flowid 20:100
这与前面的描述基本一致,所以就不做更多的解释了。
注:
在前面的例子中,我们注意到:即使 isp 客户多数离线,我们的 office 用户也仍然只
有 2 m 的带宽,这是相当浪费的。我们可以删掉 'bounded' 参数,这样,各类之间就
可以相互借用带宽了。
但是,某些类也许不希望向其它类借用带宽;比如,一条线路上的两个互为竞争对手的
isp 的情况。在这种情况下,我们可以加上关键字 'isolated'。
3. 结束语
目前,linux 所提供的 qos(服务质量)是所有操作系统中最复杂、最完善的。另外,
bsd 的 altq 应该说也相当不错;但是,在复杂性、灵活性和可扩展性等方面要落后
linux 一大截。我不太清楚微软的产品是否提供了这方面的功能。sun 的 solaris 提供
了 cbq 和 rsvp 的功能。
linux 也支持 ietf diffserv 特征。
linux 在 qos 方面众多的特征,将极大提升 linux 的市场占有率。
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器