[Linux]使用 linux 下的 TC 進行服務器流量控制

轉載本站文章請註明,轉載自:扶凱[http://www.php-oa.com]

本文鏈接: http://www.php-oa.com/2009/06/23/linux_tc.html

 

     公司一臺服務器,網絡環境太高,那臺服務器和源服務器連接下載,就跑到400M-500M,爲了控制一下,所以研究了一下TC。來做流量控制.給他控制到小點,不要讓這一臺佔了所有的網絡。TC很是強大啊,很多所謂的硬件路由器,都是基於這個做的。

TC介紹

     在 linux 中,TC 有二種控制方法 CBQ 和 HTB.HTB 是設計用來替換 CBQ 的。它是一個層次式的過濾框架.

     TC包括三個基本的構成塊:

     隊列規定 qdisc(queueing discipline )、類(class)和分類器(Classifiers)

TC 中的隊列(queueing discipline): 
     用來實現控制網絡的收發速度.通過隊列,linux可以將網絡數據包緩存起來,然後根據用戶的設置,在儘量不中斷連接(如 TCP)的前提下來平滑網絡流量.需要注意的是,linux對接收隊列的控制不夠好,所以我們一般只用發送隊列,即“控發不控收”.它封裝了其他兩個主要 TC組件(類和分類器)。內核如果需要通過某個網絡接口發送數據包,它都需要按照爲這個接口配置的qdisc(排隊規則)把數據包加入隊列。然後,內核會儘可能多地從qdisc裏面取出數據包,把它們交給網絡適配器驅動模塊。

     最簡單的 QDisc 是 pfifo 它不對進入的數據包做任何的處理,數據包採用先入先出的方式通過隊列。不過,它會保存網絡接口一時無法處理的數據包。
隊列規則包括FIFO(先進先出),RED(隨機早期探測),SFQ(隨機公平隊列)和令牌桶(Token Bucket),類基隊列(CBQ),CBQ 是一種超級隊列,即它能夠包含其它隊列(甚至其它CBQ)。

TC 中的 Class 類
     class 用來表示控制策略.很顯然,很多時候,我們很可能要對不同的IP實行不同的流量控制策略,這時候我們就得用不同的class來表示不同的控制策略了.

TC 中的 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 的應用流程

數據包->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 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

實例

使用 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章