tc 介紹html
在linux中,tc 有二種控制方法 CBQ 和 HTB.HTB 是設計用來替換 CBQ 的.HTB比CBQ更加靈活,可是CPU 開銷也更大,一般高速的鏈路會使用CBQ,通常而言HTB使用的更加普遍。HTB 的規則本質上是一個樹形結構,包括三個基本的構成塊:隊列規定 qdisc(queueing discipline) ,類(class)和分類器(Classifiers).
java
qdisc 隊列規則(queueing discipline): linux
用來實現控制網絡的收發速度.經過隊列,linux能夠將網絡數據包緩存起來,而後根據用戶的設置,在儘可能不中斷鏈接(如 tcp)的前提下來平滑網絡流量.須要注意的是,linux 對接收隊列的控制不夠好,因此咱們通常只用發送隊列,即"控發不控收".它封裝了其餘兩個主要 tc 組件(類和分類器).內核若是須要經過某個網絡接口發送數據包,它都須要按照爲這個接口配置的 qdisc 隊列規則把數據包加入隊列.而後,內核會盡量多地從 qdisc裏面取出數據包,把它們交給網絡適配器驅動模塊.緩存
最簡單的 QDisc 是 pfifo 它不對進入的數據包作任何的處理,數據包採用先入先出的方式經過隊列.不過,它會保存網絡接口一時沒法處理的數據包.常有的隊列規則包括 FIFO 先進先出,RED 隨機早期探測,SFQ 隨機公平隊列和令牌桶 Token Bucket,類基隊列 CBQ,CBQ 是一種超級隊列,即它可以包含其它隊列,甚至其它 CBQ.
服務器
Class 類網絡
class 用來表示控制策略.很顯然,不少時候,咱們極可能要對不一樣的IP實行不一樣的流量控制策略,這時候咱們就得用不一樣的class來表示不一樣的控制策略了.
tcp
Filter 規則.net
filter 用來將用戶劃入到具體的控制策略中(即不一樣的 class 中).好比,如今,咱們想對xxa,xxb兩個IP實行不一樣的控制策略(A,B),這時,咱們可用 filter 將 xxa 劃入到控制策略 A,將 xxb 劃入到控制策略 B,filter 劃分的標誌位可用 u32 打標功能或 IPtables 的 set-mark (大多使用iptables 來作標記)功能來實現.
目前,tc可使用的過濾器有:fwmark分類器,u32 分類器,基於路由的分類器和 RSVP 分類器(分別用於IPV六、IPV4)等;其中,fwmark 分類器容許咱們使用 Linux netfilter 代碼選擇流量,而 u32 分類器容許咱們選擇基於 ANY 頭的流量 .須要注意的是,filter (過濾器)是在QDisc 內部,它們不能做爲主體.
設計
tc 的應用流程unix
若是將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