各類雙邊網路加速軟體效果測試

雙邊加速即在服務端和客戶端都需要進行安裝,對資料包進行處理,區別於單邊加速,如BBR,BBR透過演算法改善服務端發包行為,只需在服務端安裝,而不用在客戶端安裝。

透過網路搜尋,目前比較流行的雙邊加速軟體大概有如下

kcptun:https://github。com/xtaci/kcptun

UDPSpeeder:https://github。com/wangyu-/UDPspeeder

udp2raw:https://github。com/wangyu-/udp2raw

kcptun

原理如下圖,加速兩邊透過TCP連線,廣域網之間使用KCP協議

各類雙邊網路加速軟體效果測試

kcp

KCP - A Fast and Reliable ARQ Protocol

簡單理解KCP是在UDP的基礎之上加上擁塞控制和超時重傳,模擬TCP的行為,在公網上,本質上還是UDP,KCP是在使用者態實現擁塞控制和超時重傳,而TCP是在核心TCP協議棧中實現的

KCP是一個快速可靠協議,能以比 TCP 浪費 10%-20% 的頻寬的代價,換取平均延遲降低 30%-40%,且最大延遲降低三倍的傳輸效果。純演算法實現,並不負責底層協議(如UDP)的收發,需要使用者自己定義下層資料包的傳送方式,以 callback的方式提供給 KCP。 連時鐘都需要外部傳遞進來,內部不會有任何一次系統呼叫。

TCP是為流量設計的(每秒內可以傳輸多少KB的資料),講究的是充分利用頻寬。而 KCP是為流速設計的(單個數據包從一端傳送到一端需要多少時間),以10%-20%頻寬浪費的代價換取了比 TCP快30%-40%的傳輸速度。TCP通道是一條流速很慢,但每秒流量很大的大運河,而KCP是水流湍急的小激流。

近年來,網路遊戲和各類社交網路都在成幾何倍數的增長,不管網路遊戲還是各類互動社交網路,互動性和複雜度都在迅速提高,都需要在極短的時間內將資料同時投遞給大量使用者,因此傳輸技術自然變為未來制約發展的一個重要因素,而開源界裡各種著名的傳輸協議,如 raknet/enet 之類,一發布都是整套協議棧一起釋出,這種形式是不利於多樣化的,我的專案只能選擇用或者不用你,很難選擇 “部分用你”,然而你一套協議棧設計的再好,是非常難以滿足不同角度的各種需求的。

因此 KCP 的方式是把協議棧 “拆開”,讓大家可以根據專案需求進行靈活的調整和組裝,你可以下面加一層 reed solomon 的糾刪碼做 FEC,上面加一層類 RC4/Salsa20 做流加密,握手處再設計一套非對稱金鑰交換,底層 UDP 傳輸層再做一套動態路由系統,同時探測多條路徑,選最好路徑進行傳輸。這些不同的 “協議單元” 可以像搭建積木一般根據需要自由組合,保證 “簡單性” 和 “可拆分性”,這樣才能靈活適配多變的業務需求,哪個模組不好,換了就是。

未來傳輸方面的解決方案必然是根據使用場景深度定製的,因此給大家一個可以自由組合的 “協議單元” ,方便大家整合在自己的協議棧中。

如果網路永遠不卡,那 KCP/TCP 表現類似,但是網路本身就是不可靠的,丟包和抖動無法避免(否則還要各種可靠協議幹嘛)。在內網這種幾乎理想的環境裡直接比較,大家都差不多,但是放到公網上,放到3G/4G網路情況下,或者使用內網丟包模擬,差距就很明顯了。公網在高峰期有平均接近10%的丟包,wifi/3g/4g下更糟糕,這些都會讓傳輸變卡。

總的來說, KCP 採用了與 TCP 幾乎相同的架構, 在使用者態實現了確認、ARQ、流量控制與擁塞控制機制, 但 KCP 一定程度上破壞了公平性, TCP 設計的初衷之一便是在全域性角度達到公平, 因此會有慢開始、丟包退讓等機制(RFC 5681), 而 KCP 在多處修改了相應的策略, 當網路環境不佳時, KCP 將比 TCP 擁有更好的效能, TCP 經過了這麼多年的發展, 本身已經是一個足夠完善的協議, 對於擁塞控制也做了大量的工作, 所做的一切就是為了能讓全域性的平均效能達到最好, 對於 KCP 的爭議也有很多, 單一維度無法直接評判 KCP 協議本身, 但可以確定的是當大量客戶端都開始採用 KCP 時, 那 KCP 也就失去它的優勢了

UDPSpeeder

A Tunnel which Improves your Network Quality on a High-latency Lossy Link by using Forward Error Correction, possible for All Traffics(TCP/UDP/ICMP)

工作模式如下圖

各類雙邊網路加速軟體效果測試

主要原理是透過冗餘資料來對抗網路的丟包,傳送冗餘資料的方式支援FEC(Forward Error Correction)和多倍發包,其中FEC演算法是Reed-Solomon。

各類雙邊網路加速軟體效果測試

簡單理解就是透過傳送冗餘資料包對抗丟包

udp2raw

A Tunnel which Turns UDP Traffic into Encrypted UDP/FakeTCP/ICMP Traffic by using Raw Socket,helps you Bypass UDP FireWalls(or Unstable UDP Environment)

工作模式

各類雙邊網路加速軟體效果測試

簡單理解就是透過rawSocket模擬TCP的包頭和行為迷惑NAT裝置

測試環境

環境準備

三臺主機,主機A為被測主機

主機A——洛杉磯(資料中心頻寬接入,頻寬100Mbps)

主機B——中國(家庭頻寬接入,頻寬100Mbps)

主機C——洛杉磯(資料中心頻寬接入,頻寬50Mbps )

假設A主機公網IP為44。55。66。77

測試內容為

時延測試(ping)

下載速度測試(wget)

準備100M和500M的檔案,啟HTTP Server

dd if=/dev/zero bs=100M count=1 > ~/100Mdd if=/dev/zero bs=500M count=1 > ~/500Mcd ~ && python -m SimpleHTTPServer 8388

下載測試命令,注意寫入到

/dev/null

避免受本地磁碟寫入速度影響

wget -O /dev/null http://127。0。0。1:8388/100M​wget -O /dev/null http://127。0。0。1:8388/500M

kcptun、UDPspeeder、udp2raw安裝,進入對應github頁面,下載二進位制可執行檔案到

/usr/bin/

即可

裸機測試

首先不安裝任何加速,進行時延測試

B到A:丟包率9%,平均時延201ms

300 packets transmitted, 271 received, 9% packet loss, time 299310msrtt min/avg/max/mdev = 174。219/201。209/293。486/36。907 ms

C到A:丟包率0%,平均時延0。79

300 packets transmitted, 300 received, 0% packet loss, time 306006msrtt min/avg/max/mdev = 0。437/0。793/14。616/1。108 ms

下載速度測試

B到A:受丟包和延遲影響,緩慢增長,大概10s到達峰值

100%[=====================>] 104,857,600 5。42MB/s in 17s2022-01-01 21:43:24 (6。01 MB/s) - ‘/dev/null’ saved [104857600/104857600]​​100%[=====================>] 524,288,000 9。53MB/s in 62s2022-01-01 21:44:49 (8。12 MB/s) - ‘/dev/null’ saved [524288000/524288000]​

C到A:無丟包和延遲,速度能立即到達峰值,峰值速度相對的較低,因為C的頻寬只有50Mbps

100%[=======================>] 104,857,600 5。68MB/s in 18s​2022-01-01 21:46:24 (5。68 MB/s) - ‘/dev/null’ saved [104857600/104857600]​​100%[=======================>] 524,288,000 5。68MB/s in 88s​2022-01-01 21:48:43 (5。68 MB/s) - ‘/dev/null’ saved [524288000/524288000]​

kcptun

使用預設引數

# server端kcptun_server -t “127。0。0。1:8388” -l “:5201”​# client端kcptun_client -r “44。55。66。77:5201” -l “127。0。0。1:8388”

由於是TCP隧道,無法接入Wireguard,無法測試延遲,只能測試下載速度

下載速度測試

B到A:立即到達峰值,峰值速度有所增加

立即到達峰值,峰值速度有所增加,增加了2MB/s+100%[======================>] 104,857,600 6。05MB/s in 12s​2022-01-01 21:54:16 (8。32 MB/s) - ‘/dev/null’ saved [104857600/104857600]​​立即到達峰值,峰值速度有所增加,增加不大100%[======================>] 524,288,000 5。60MB/s in 59s​2022-01-01 21:56:00 (8。41 MB/s) - ‘/dev/null’ saved [524288000/524288000]​

C到A:立即到達峰值,

速度爆炸

,突破了C的頻寬限制,

看樣子使用kcptun確實速度有提升

立即到達峰值,速度爆炸,突破了C的頻寬限制100%[======================>] 104,857,600 47。5MB/s in 2。1s​2022-01-01 21:57:08 (47。5 MB/s) - ‘/dev/null’ saved [104857600/104857600]​​立即到達峰值,速度爆炸,突破了C的頻寬限制100%[=======================>] 524,288,000 49。6MB/s in 10s​2022-01-01 21:58:01 (47。8 MB/s) - ‘/dev/null’ saved [524288000/524288000]

kcptun+udp2raw

# udp2raw server端udp2raw -s -l0。0。0。0:5201 -r127。0。0。1:8888 -k “passwd” ——raw-mode faketcp ——cipher-mode xor -a ——fix-gro​# udp2raw client端udp2raw -c -l127。0。0。1:3333 -r44。55。66。77:5201 -k “passwd” ——raw-mode faketcp ——cipher-mode xor -a ——fix-gro​# kcptun server端kcptun_server -t “127。0。0。1:8388” -l “127。0。0。1:8888” ​# kcptun client端kcptun_client -r “127。0。0。1:3333” -l “127。0。0。1:8388”

下載速度測試

B到A:立即到達峰值,峰值速度變化不大

100%[=========================>] 104,857,600 9。45MB/s in 11s​2022-01-01 22:05:24 (9。42 MB/s) - ‘/dev/null’ saved [104857600/104857600]​​100%[==========================>] 524,288,000 9。37MB/s in 65s​2022-01-01 22:09:14 (7。71 MB/s) - ‘/dev/null’ saved [524288000/524288000]​

C到A:立即到達峰值,峰值速度下降約一半

​100%[=======================================>] 104,857,600 23。5MB/s in 4。3s​2022-01-01 22:10:05 (23。3 MB/s) - ‘/dev/null’ saved [104857600/104857600]​​100%[=======================================>] 524,288,000 26。2MB/s in 18s​2022-01-01 22:10:37 (27。1 MB/s) - ‘/dev/null’ saved [524288000/524288000]​

結論:如無明顯QoS,可直接使用kcptun,如QoS速度下降甚至埠,可在外套一層udp2raw

UDPspeeder

# 在server端執行speederv2 -s -l0。0。0。0:5201 -r127。0。0。1:8388 -f20:10 -k “passwd” ——mode 0​# 在client端執行speederv2 -c -l127。0。0。1:8388 -r44。55。66。77:5201 -f20:10 -k “passwd” ——mode 0

由於UDPspeeder監聽的是UDP埠,無法直接使用HTTP,因此引入Wireguard,配置如下

# 服務端[Interface]Address = 5。5。5。1/24ListenPort = 8388PrivateKey = aHWomHYVWebT+lAPyZcofEfdQYXdFOXpVWRKD91OyXA=​[Peer]PublicKey = 451o6In0DqSTyg1GE4WzrK4Z0BLuFXTrjdqjBJ/RLwc=AllowedIPs = 5。5。5。2/32​# 客戶端[Interface]Address = 5。5。5。2/24PrivateKey = oAaT5OjURGvVqs/pbMa2HAsZXpbwNQCEzW0MZBmGJ1Y=​[Peer]PublicKey = 1yrnzlpVNhpQyyBj0oehVqCaL/06RjK/tcd3icMuZ0Q=AllowedIPs = 5。5。5。1/32Endpoint = 127。0。0。1:8388PersistentKeepalive = 15

首先進行時延測試

B到A:丟包率10%,丟包率有所增加

300 packets transmitted, 268 received, 10% packet loss, time 299307msrtt min/avg/max/mdev = 195。482/239。424/319。491/49。255 ms

C到A:本身不丟包,測試無意義

下載速度測試

B到A:速度緩慢增加,20:10似乎發包率不夠,速度波動很大

100%[===========================>] 104,857,600 8。89MB/s in 12s​2022-01-01 22:21:26 (8。03 MB/s) - ‘/dev/null’ saved [104857600/104857600]​# 速度波動很大,測試幾次才測試完100%[===========================>] 524,288,000 6。31MB/s in 1m 42s2022-01-01 22:29:08 (4。92 MB/s) - ‘/dev/null’ saved [524288000/524288000]

C到A:速度下降嚴重

100%[=============================>] 104,857,600 2。80MB/s in 30s2022-01-01 22:30:43 (3。32 MB/s) - ‘/dev/null’ saved [104857600/104857600]​​100%[==============================>] 524,288,000 3。43MB/s in 2m 32s2022-01-01 22:33:50 (3。29 MB/s) - ‘/dev/null’ saved [524288000/524288000]

結論:不知道是配置引數不對還是因為引入了Wireguard,總體速度達不到kcptun,甚至達不到裸機測試

UDPspeeder+udp2raw

# 在server端執行udp2raw -s -l0。0。0。0:5201 -r127。0。0。1:8888 -k “passwd” ——raw-mode faketcp ——cipher-mode xor -a ——fix-gro​# 在client端執行udp2raw -c -l127。0。0。1:3333 -r44。55。66。77:5201 -k “passwd” ——raw-mode faketcp ——cipher-mode xor -a ——fix-gro​​# 在server端執行speederv2 -s -l0。0。0。0:5201 -r127。0。0。1:8388 -f20:10 -k “passwd” ——mode 0​# 在client端執行speederv2 -c -l127。0。0。1:8388 -r44。55。66。77:5201 -f20:10 -k “passwd” ——mode 0

由於UDPspeeder監聽的是UDP埠,無法直接使用HTTP,因此引入Wireguard,配置如下

# 服務端[Interface]Address = 5。5。5。1/24ListenPort = 8388PrivateKey = aHWomHYVWebT+lAPyZcofEfdQYXdFOXpVWRKD91OyXA=​[Peer]PublicKey = 451o6In0DqSTyg1GE4WzrK4Z0BLuFXTrjdqjBJ/RLwc=AllowedIPs = 5。5。5。2/32​# 客戶端[Interface]Address = 5。5。5。2/24PrivateKey = oAaT5OjURGvVqs/pbMa2HAsZXpbwNQCEzW0MZBmGJ1Y=​[Peer]PublicKey = 1yrnzlpVNhpQyyBj0oehVqCaL/06RjK/tcd3icMuZ0Q=AllowedIPs = 5。5。5。1/32Endpoint = 127。0。0。1:8388PersistentKeepalive = 15

首先進行時延測試

B到A:同樣300個包,丟包率0%,確實有所提升,不清楚是QoS影響還是網路本身波動

300 packets transmitted, 300 received, 0% packet loss, time 299403msrtt min/avg/max/mdev = 200。413/202。806/222。987/2。978 ms

C到A:本身不丟包,測試無意義

下載速度測試

B到A:速度緩慢增加,20:10似乎發包率不夠,速度波動很大,達不到裸機

100%[===============================>] 104,857,600 6。70MB/s in 16s2022-01-01 22:51:54 (6。28 MB/s) - ‘/dev/null’ saved [104857600/104857600]​​100%[===============================>] 524,288,000 6。08MB/s in 73s2022-01-01 22:53:34 (6。81 MB/s) - ‘/dev/null’ saved [524288000/524288000]

測試結果

時延與丟包:

UDPspeeder+udp2raw

組合對丟包有改善,不知是否QoS影響,需自測

方向

裸機

UDPspeeder

UDPspeeder+udp2raw

下載速度

套上kcptun速度確實有提升

UDPspeeder反而會使速度下降

kcptun+udp2raw速度下降

UDPspeeder+udp2raw速度下降

方向

裸機

kcptun

kcptun+udp2raw

UDPspeeder

UDPspeeder+udp2raw

建議:如無明顯QoS,可直接使用kcptun,如QoS速度下降甚至埠,可在外套一層udp2raw

因網路環境複雜,且各種加速工具引數配置組合較多,稍有不慎則會對速度影響大,故

以上建議和結論僅供參考

參考

https://github。com/xtaci/kcptun

https://github。com/skywind3000/kcp

https://github。com/wangyu-/UDPspeeder

https://github。com/wangyu-/udp2raw