多WAN帶寬疊加——Multiwan篇


經常在論壇上看到對多撥之后帶寬無法疊加的抱怨。經過一段時間的研究,發現目前主流有三種工具來幫助我們實現多WAN帶寬疊加,分別是:

而且更有高手能夠不使用以上工具,而直接使用linux的網絡命令配置出同樣的多WAN帶寬疊加的效果。那么到底用何種工具,如何配置才能真正疊加帶寬呢?為了回答這個問題,我們需要動手來做實驗。在實踐來檢驗工具和方案的效果,並且進一步了解工具背后的原理。

實驗環境

使用實際的物理機和路由器來實驗是非常困難的。為了保證實驗能夠准確(不受實際帶寬的干擾)並且成本低(不需要來回走動,使用多台機器),我們需要使用vmware的虛擬機,在x86的OpenWRT平台上來完成這個實驗。下面是我們首先建立的一個環境的網絡拓撲圖:

在lab-sleepy上啟動了一個nginx進程,監聽8080端口,提供了一個1.bin文件供客戶端下載。
在lab-doc上執行curl http://10.2.0.100:8080/1.bin -o 1.bin,可以看到限速是成功的,大概就是7kb/s(合56kbps)。

1 root@lab-doc:/usr/share/download# curl http://10.2.0.100:8080/1.bin -o 1.bin
2   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
3                                  Dload  Upload   Total   Spent    Left  Speed
4   0  119M    0  114k    0     0   6225      0  5:34:50  0:00:18  5:34:32  4194

在lab-doc上執行traceroute 10.2.0.100可以看到中間經過的兩個路由器

1 root@lab-doc:/usr/share/download# traceroute 10.2.0.100
2 traceroute to 10.2.0.100 (10.2.0.100), 30 hops max, 38 byte packets
3  1  10.0.0.2 (10.0.0.2)  0.413 ms  0.265 ms  0.259 ms
4  2  10.1.2.2 (10.1.2.2)  0.609 ms  0.445 ms  0.421 ms
5  3  10.2.0.100 (10.2.0.100)  0.625 ms  0.536 ms  0.491 ms

在lab-bashful上執行ip route可以看到這個時候家庭路由器的路由狀態,有三條獨立的出口。

1 root@lab-bashful:~# ip route
2 10.0.0.0/24 dev eth0  proto kernel  scope link  src 10.0.0.2
3 10.1.0.0/24 dev eth1  proto kernel  scope link  src 10.1.0.100
4 10.1.1.0/24 dev eth2  proto kernel  scope link  src 10.1.1.100
5 10.1.2.0/24 dev eth3  proto kernel  scope link  src 10.1.2.100
6 default via 10.1.2.2 dev eth3
7 default via 10.1.1.2 dev eth2
8 default via 10.1.0.2 dev eth1

多WAN帶寬合並的目標就是把這三條獨立的出口合並成一條來使用,使得總帶寬可以56kbps * 3達到168kbps,實際下載速度從7kb/s提升到21kb/s。

實驗:使用multiwan疊加帶寬(模式Compatibility Balancer,不同出口網關,相同目標服務器)

在lab-bashful上安裝multiwan。配置文件如下:

 1 root@lab-bashful:~# cat /etc/config/multiwan
 2 
 3 config 'multiwan' 'config'
 4         option 'default_route' 'balancer'
 5 
 6 config 'interface' 'wan1'
 7         option 'weight' '10'
 8         option 'health_interval' '10'
 9         option 'timeout' '3'
10         option 'health_fail_retries' '3'
11         option 'health_recovery_retries' '5'
12         option 'failover_to' 'balancer'
13         option 'dns' 'auto'
14         option 'icmp_hosts' 'gateway'
15 
16 config 'interface' 'wan2'
17         option 'weight' '10'
18         option 'health_interval' '10'
19         option 'timeout' '3'
20         option 'health_fail_retries' '3'
21         option 'health_recovery_retries' '5'
22         option 'failover_to' 'balancer'
23         option 'dns' 'auto'
24         option 'icmp_hosts' 'gateway'
25 
26 config 'interface' 'wan3'
27         option 'weight' '10'
28         option 'health_interval' '10'
29         option 'timeout' '3'
30         option 'health_fail_retries' '3'
31         option 'health_recovery_retries' '5'
32         option 'failover_to' 'balancer'
33         option 'dns' 'auto'
34         option 'icmp_hosts' 'gateway'

重啟路由器,確保multiwan啟用之后,執行ip route查看路由規則是否有變化

1 root@lab-bashful:~# ip route
2 10.0.0.0/24 dev eth0  proto kernel  scope link  src 10.0.0.2
3 10.1.0.0/24 dev eth1  proto kernel  scope link  src 10.1.0.100
4 10.1.1.0/24 dev eth2  proto kernel  scope link  src 10.1.1.100
5 10.1.2.0/24 dev eth3  proto kernel  scope link  src 10.1.2.100
6 default via 10.1.2.2 dev eth3
7 default via 10.1.1.2 dev eth2
8 default via 10.1.0.2 dev eth1

不曾見到路由規則發現變化,但是觀察iptables,發現多了許多規則。最明顯之處在於這三條規則

Rule#        Pkts.        Traffic        Target        Prot.        Flags        In        Out        Source        Destination        Options
1        0        0.00 B        FW1MARK        all        --        *        *        0.0.0.0/0        0.0.0.0/0        mark match 0x2 statistic mode random probability 0.330000
2        0        0.00 B        FW2MARK        all        --        *        *        0.0.0.0/0        0.0.0.0/0        mark match 0x2 statistic mode random probability 0.500000
3        0        0.00 B        FW3MARK        all        --        *        *        0.0.0.0/0        0.0.0.0/0        mark match 0x2 statistic mode random probability 1.000000


看來mulitwan的compatibility balancer是用iptables實現的multiwan,而不是路由表。
使用curl單線程下載,速度無變化。多個curl下載,總帶寬也不見漲。
為什么呢?我們來看看multiwan在compatibility balancer模式下到底干了什么。

實驗:無疊加腳本,系統默認行為

先把multiwan刪掉,看看干凈的OpenWRT在三個default route出口的情況下,行為是怎樣的。

 1 root@lab-bashful:~# ip route
 2 10.0.0.0/24 dev eth0  proto kernel  scope link  src 10.0.0.2
 3 10.1.0.0/24 dev eth1  proto kernel  scope link  src 10.1.0.100
 4 10.1.1.0/24 dev eth2  proto kernel  scope link  src 10.1.1.100
 5 10.1.2.0/24 dev eth3  proto kernel  scope link  src 10.1.2.100
 6 default via 10.1.2.2 dev eth3
 7 default via 10.1.1.2 dev eth2
 8 default via 10.1.0.2 dev eth1
 9 
10 root@lab-doc:/usr/share/download# traceroute 10.2.0.100
11 traceroute to 10.2.0.100 (10.2.0.100), 30 hops max, 38 byte packets
12  1  10.0.0.2 (10.0.0.2)  0.225 ms  0.174 ms  0.190 ms
13  2  10.1.2.2 (10.1.2.2)  0.351 ms  0.339 ms  0.282 ms
14  3  10.2.0.100 (10.2.0.100)  0.383 ms  0.293 ms  0.262 ms
15 
16 root@lab-bashful:~# ip route show cache | grep 10.2.0.100
17 10.2.0.100 from 10.0.0.100 via 10.1.2.2 dev eth3  src 10.0.0.2
18 10.0.0.100 from 10.2.0.100 dev eth0  src 10.1.2.100

重復實驗幾次,仍然是一樣的。這個狀態就和很多朋友遇到的情況一樣,在多WAN腳本沒有生效的狀況下,流量只會從最后撥上的WAN出口走,這個例子里就是總是從WAN3出去。


實驗:使用multiwan疊加帶寬(模式Compatibility Balancer,不同出口網關,相同目標服務器)
重新把multiwan裝上,看看traceroute是否發生變化

1 root@lab-doc:/usr/share/download# traceroute 10.2.0.100
2 traceroute to 10.2.0.100 (10.2.0.100), 30 hops max, 38 byte packets
3  1  10.0.0.2 (10.0.0.2)  0.218 ms  0.122 ms  0.082 ms
4  2  10.1.1.2 (10.1.1.2)  0.204 ms  0.141 ms  0.156 ms
5  3  10.2.0.100 (10.2.0.100)  0.488 ms  0.273 ms  0.386 ms
6 
7 root@lab-bashful:~# ip route show cache | grep 10.2.0.100
8 10.2.0.100 from 10.0.0.100 via 10.1.1.2 dev eth2  src 10.0.0.2
9 10.0.0.100 from 10.2.0.100 dev eth0  src 10.1.1.100

可以發現,走的路由是eth2而不是eth3。重復執行traceroute無變化,執行ip route flush cache之后,路由會發生變化。

1 root@lab-bashful:~# ip route flush cache
2 
3 root@lab-doc:/usr/share/download# traceroute 10.2.0.100
4 traceroute to 10.2.0.100 (10.2.0.100), 30 hops max, 38 byte packets
5  1  10.0.0.2 (10.0.0.2)  0.198 ms  0.150 ms  0.146 ms
6  2  10.1.2.2 (10.1.2.2)  0.314 ms  0.261 ms  0.170 ms
7  3  10.2.0.100 (10.2.0.100)  0.349 ms  0.303 ms  0.249 ms

由此可見,multiwan不是什么都沒做的,至少不同的出口路由,在路由規則沒有被緩存的情況下,是有一定可能性被系統選擇使用的。每次執行完curl 之后,在lab-bashful上執行一次ip route flush cache,再次執行curl有一定概率走另外一條WAN。

實際上multiwan在Comptability模式的LoadBalancer下,不僅僅使用了iptables,還有使用了自己的路由表。

第一步:
Chain MultiWanRules (References: 1)
Rule #        Pkts.        Traffic        Target        Prot.        Flags        In        Out        Source        Destination        Options
1        2627        173.36 KB        LoadBalancer        all        --        *        *        0.0.0.0/0        0.0.0.0/0        mark match 0x0
第二步:
Chain LoadBalancer (References: 1)
Rule #        Pkts.        Traffic        Target        Prot.        Flags        In        Out        Source        Destination        Options
1        2715        180.58 KB        MARK        all        --        *        *        0.0.0.0/0        0.0.0.0/0        MARK set 0x1
2        2715        180.58 KB        CONNMARK        all        --        *        *        0.0.0.0/0        0.0.0.0/0        CONNMARK save
第三步:
root@lab-bashful:~# ip rule
0:      from all lookup local
9:      from all fwmark 0x1 lookup LoadBalancer
10:     from 10.1.0.100 lookup MWAN1
11:     from all fwmark 0x10 lookup MWAN1
20:     from 10.1.1.100 lookup MWAN2
21:     from all fwmark 0x20 lookup MWAN2
30:     from 10.1.2.100 lookup MWAN3
31:     from all fwmark 0x30 lookup MWAN3
32766:  from all lookup main
32767:  from all lookup default

 

 

第四步:
root@lab-bashful:~# ip route show table LoadBalancer
10.0.0.0/24 dev eth0  proto kernel  scope link  src 10.0.0.2
10.1.0.0/24 dev eth1  proto kernel  scope link  src 10.1.0.100
10.1.1.0/24 dev eth2  proto kernel  scope link  src 10.1.1.100
10.1.2.0/24 dev eth3  proto kernel  scope link  src 10.1.2.100
default  proto static
        nexthop via 10.1.0.2  dev eth1 weight 10
        nexthop via 10.1.1.2  dev eth2 weight 10
        nexthop via 10.1.2.2  dev eth3 weight 10

所以實現的方式是先用iptables給packet打上標記,0x1。然后在全局路由表里設置規則,所有打了0x1標記的包,都走獨立的名叫 LoadBalancer的路由表,然后在LoadBalancer這個路由表里設置一條多出口的default route並設置權重(weight)。Linux內核會根據權重來選擇具體走哪條路由。
目前我所看見的所有的多WAN疊加腳本的原理都是一樣的。在連接建立的時候,由路由器來選擇一條路由。因為default路由是nexthop的形式,所 以會這個連接用WAN1,下一個連接走WAN2。連接建立了之后,這個出口不能更改的(原因可能是因為NAT的需要)。由於路由表有緩存,所以對於同一個 目標IP,一旦走了某個特定的WAN,比如WAN1,之后對於所有指向這個目標IP的請求都只會走WAN1,因為default路由只有在緩存中沒有匹配 的路由路徑的時候才起作用。所以我們需要用ip route flush cache來使得第二次curl走不同的WAN。或者用morfast的辦法 http://www.morfast.net/blog/linux/load-balance/ 修改內核參數禁用路由緩存。

 1 root@lab-bashful:~# echo -1 > /proc/sys/net/ipv4/rt_cache_rebuild_count
 2 
 3 root@lab-doc:~# traceroute 10.2.0.100
 4 traceroute to 10.2.0.100 (10.2.0.100), 30 hops max, 38 byte packets
 5  1  10.0.0.2 (10.0.0.2)  0.222 ms  0.144 ms  0.138 ms
 6  2  10.1.2.2 (10.1.2.2)  0.283 ms  10.1.1.2 (10.1.1.2)  0.256 ms  0.287 ms
 7  3  10.2.0.100 (10.2.0.100)  0.505 ms  0.398 ms  0.355 ms
 8 root@lab-doc:~# traceroute 10.2.0.100
 9 traceroute to 10.2.0.100 (10.2.0.100), 30 hops max, 38 byte packets
10  1  10.0.0.2 (10.0.0.2)  0.223 ms  0.179 ms  0.168 ms
11  2  10.1.1.2 (10.1.1.2)  0.403 ms  0.353 ms  0.255 ms
12  3  10.2.0.100 (10.2.0.100)  0.378 ms  0.392 ms  *
13 
14 router@router-dev:~/Downloads$ aria2c -x4 -s4 -j4 http://10.2.0.100:8080/1.bin
15 [#1 SIZE:5.2MiB/119.2MiB(4%) CN:4 SPD:20.4KiBs ETA:1h35m12s]

由此可見通過修改內核參數,可以使得相同目標IP,建立不同連接也走不同的WAN。

實驗:使用multiwan疊加帶寬(模式Fast Balancer,不同出口網關,相同目標服務器)

這次我們把multiwan設置為Fast Balancer。其實現方式就不再是ip route nexthop了,變成了用iptables來實現選擇性路由。

第一步:
Chain MultiWanRules (References: 1)
Rule #        Pkts.        Traffic        Target        Prot.        Flags        In        Out        Source        Destination        Options
1        21838        1.46 MB        FastBalancer        all        --        *        *        0.0.0.0/0        0.0.0.0/0        mark match 0x0
之前在這里的Target是LoadBalancer。

第二步:
Chain FastBalancer (References: 1)
Rule #        Pkts.        Traffic        Target        Prot.        Flags        In        Out        Source        Destination        Options
1        21838        1.46 MB        MARK        all        --        *        *        0.0.0.0/0        0.0.0.0/0        MARK set 0x2
2        21838        1.46 MB        CONNMARK        all        --        *        *        0.0.0.0/0        0.0.0.0/0        CONNMARK save
之前LoadBalancer設置的是0x1。

第三步:
Chain MultiWanLoadBalancer (References: 1)
Rule #        Pkts.        Traffic        Target        Prot.        Flags        In        Out        Source        Destination        Options
1        7166        490.46 KB        FW1MARK        all        --        *        *        0.0.0.0/0        0.0.0.0/0        mark match 0x2 statistic mode random probability 0.330000
2        7296        499.04 KB        FW2MARK        all        --        *        *        0.0.0.0/0        0.0.0.0/0        mark match 0x2 statistic mode random probability 0.500000
3        7376        504.89 KB        FW3MARK        all        --        *        *        0.0.0.0/0        0.0.0.0/0        mark match 0x2 statistic mode random probability 1.000000
第一條規則是1/3的概率,第二條是剩下的50%,也就是總的1/3,最后100%,也就是1-1/3-1/3=1/3。所以三條規則的權重是一樣的,和設置的1,1,1是一樣的比例。

第四步:
Chain FW1MARK (References: 3)
Rule #        Pkts.        Traffic        Target        Prot.        Flags        In        Out        Source        Destination        Options
1        7326        541.71 KB        MARK        all        --        *        *        0.0.0.0/0        0.0.0.0/0        MARK set 0x10
2        7326        541.71 KB        CONNMARK        all        --        *        *        0.0.0.0/0        0.0.0.0/0        CONNMARK save

第五步:
root@lab-bashful:~# ip rule
0:      from all lookup local
9:      from all fwmark 0x1 lookup LoadBalancer
10:     from 10.1.0.100 lookup MWAN1
11:     from all fwmark 0x10 lookup MWAN1
20:     from 10.1.1.100 lookup MWAN2
21:     from all fwmark 0x20 lookup MWAN2
30:     from 10.1.2.100 lookup MWAN3
31:     from all fwmark 0x30 lookup MWAN3
32766:  from all lookup main
32767:  from all lookup default


第六步:
root@lab-bashful:~# ip route show table MWAN1
10.0.0.0/24 dev eth0  proto kernel  scope link  src 10.0.0.2
10.1.0.0/24 dev eth1  proto kernel  scope link  src 10.1.0.100
10.1.1.0/24 dev eth2  proto kernel  scope link  src 10.1.1.100
10.1.2.0/24 dev eth3  proto kernel  scope link  src 10.1.2.100
default via 10.1.0.2 dev eth1  proto static  src 10.1.0.100

這種實現方式的好處就是,對於同一個目標IP,不同連接也有可能走不同的WAN,帶寬疊加效果更好。用Compatibility模式的Balancer 的時候,不禁用路由緩存的話,每次traceroute的結果都是一樣。但是使用了Fast模式的Balancer,即便有路由緩 存,traceroute也會發生變化,因為每次新建立的連接,第三步都會重新按概率派發到不同的下級規則。用aira2c測試四線程並發下載,也可以達 到最大帶寬。所以Fast Balancer在這個設置下也可以疊加帶寬,而且疊加效果似乎還不錯,連同目標IP都能夠疊加。
但是在openwrt的論壇上mwan2的作者說multiwan使用了太多的iptables規則。

Why should i use mwan2 instead of multi-wan ?:
- It is faster; mwan2 uses less iptables-rules.
- It is more configurable; mwan2 can handle multiple levels of backup interfaces, load-balanced or not.
- It is compatible; mwan2 uses flowmask to be compatible with other packages (such as OpenVPN, PPTP VPN, QoS-script, Tunnels, etc) and you can configure destinations to fall-back to the default routing table.



實驗:使用multiwan疊加帶寬(模式Compatibility Balancer,相同出口網關,相同目標服務器)
更新一下網絡拓撲圖:



在相同網關的情況下,traceroute已經無法得知走的是哪條路由了。每次的結果都是一樣的(因為網關只有一個嘛)。但是在lab-bashful上查看路由緩存還是可以看出端倪來的

1 #從lab-doc發幾個包到lab-sleepy
2 root@lab-bashful:~# ip route show cache | grep 10.2.0.100
3 10.0.0.100 from 10.2.0.100 dev eth0  src 10.1.0.100
4 10.2.0.100 from 10.0.0.100 via 10.1.0.2 dev eth3  src 10.0.0.2
5 root@lab-bashful:~# ip route flush cache
6 #從lab-doc發幾個包到lab-sleepy
7 root@lab-bashful:~# ip route show cache | grep 10.2.0.100
8 10.2.0.100 from 10.0.0.100 via 10.1.0.2 dev eth1  src 10.0.0.2
9 10.0.0.100 from 10.2.0.100 dev eth0  src 10.1.0.100

可以看到有的時候走的是eth3,有的時候走的是eth0。那么實際的下載速度是不是能夠疊加呢?
使用aria2c並發四線程下載,用內核參數禁用掉lab-bashfuld的路由緩存,下載速度可以達到19.8kb/s。
也就是說使用multiwan,兼容模式的balancer,相同網關是可以疊加的。
我之前的印象是,網關相同的話,multiwan無法疊加。

1 root@lab-bashful:~# ip route show table LoadBalancer
2 10.0.0.0/24 dev eth0  proto kernel  scope link  src 10.0.0.2
3 10.1.0.0/24 dev eth1  proto kernel  scope link  src 10.1.0.100
4 default  proto static
5         nexthop via 10.1.0.2  dev eth1 weight 10
6         nexthop via 10.1.0.2  dev eth2 weight 10
7         nexthop via 10.1.0.2  dev eth3 weight 10

難道是我記錯了嗎?實驗一下Fast Balancer看看

實驗:使用multiwan疊加帶寬(模式Fast Balancer,相同出口網關,相同目標服務器)

 1 root@lab-bashful:~# ip route show table MWAN1
 2 10.0.0.0/24 dev eth0  proto kernel  scope link  src 10.0.0.2
 3 10.1.0.0/24 dev eth1  proto kernel  scope link  src 10.1.0.100
 4 default via 10.1.0.2 dev eth1  proto static  src 10.1.0.100
 5 root@lab-bashful:~# ip route show table MWAN2
 6 10.0.0.0/24 dev eth0  proto kernel  scope link  src 10.0.0.2
 7 10.1.0.0/24 dev eth1  proto kernel  scope link  src 10.1.0.100
 8 default via 10.1.0.2 dev eth1  proto static  src 10.1.0.101
 9 root@lab-bashful:~# ip route show table MWAN3
10 10.0.0.0/24 dev eth0  proto kernel  scope link  src 10.0.0.2
11 10.1.0.0/24 dev eth1  proto kernel  scope link  src 10.1.0.100
12 default via 10.1.0.2 dev eth1  proto static  src 10.1.0.102

啊偶,Fast Balancer確實對於相同網關有BUG,三個路由表(MWAN1,MWAN2,MWAN3)都是相同的出口(IP相同,設備相同)。
用多線程下載實測,確實沒有疊加!手工修改MWAN2和MWAN3之后,恢復正常。

【小結】

自此,本實驗第一部分告一段落。本次實驗包括了multiwan的測試,接下來會有后續實驗測試m-route,nwan和mwan2的行為。
1、不同網關,Compatibility => 原理是ip route nexthop,疊加成功(相同目標IP,需要禁用路由緩存)
2、不同網關,Fast => 原理是iptables, mark, 特定routing table, default route,疊加成功(相同IP無需禁用路由緩存)
3、相同網關,Compatibility => 同1
4、相同網關,Fast => 疊加失敗,每個mark的routing table都被設置成為了相同的出口

 

 

 

【轉自】http://www.openwrt.org.cn/bbs/thread-9848-1-1.html

【相關資料】

  http://www.hangge.com/blog/cache/detail_601.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM