1. 程式人生 > >[NewLife.Net]單機400萬長連線壓力測試

[NewLife.Net]單機400萬長連線壓力測試

目標

對網路庫NewLife.Net進行單機百萬級長連線測試,並持續收發資料,檢測網路庫穩定性。

【2020年8月1日晚上22點】

先上原始碼:https://github.com/NewLifeX/NewLife.Net

 

結論,8月1日晚達到200萬,8月2日下午達到404萬。

 

上一次百萬級壓測是2017年4月1日,失敗了,只達到84.5萬。後來做了一次吞吐量壓測。

技術革新

自上一次百萬級壓測(2017.4.1)以來,網路庫進行了諸多細節優化(沒有調整架構),特別優化了記憶體拷貝和多執行緒操作。

上次購買了20多臺高配大資料伺服器(16C64G和8C16G),每臺發起5萬Tcp長連線,純人肉方式,相當累。這次從泥水佬那裡學到本地配置多IP地址建立更多連線的方式,大大節省了伺服器資源和人力成本。每臺伺服器設定20個IP,每個IP發起5萬Tcp長連線。

測試程式也從.Net 4.5升級到了.Net Core 3.1,效能提升可觀。

 

伺服器資源

阿里雲上海區共購買6臺12C24G的計算型C5伺服器,按照搶佔型例項購買,晚上特別便宜。平時3.7每小時的價格,現在0.355就可以拿到。

這次壓測對網路要求極高,所以選擇的伺服器必須有高頻寬以及高PPS,務必是同一個機房,便於內網測試。

第一次購買的002因為設定IP失誤導致弄殘了伺服器,不得不釋放重新購買。

001~004配置多IP花了很長時間,後來才想到用命令批量設定。

預設每個ECS只有一個私網IP,可以再增加9個,一共10個。

經@景洋 提醒,ECS可以通過 繫結彈性網絡卡,得到20個IP地址,後面的005/002/006都有20個IP。

 

環境準備

優化Tcp引數

Windows預設只能使用5000個埠,需要優化Tcp引數設定。

把碼神工具拷貝到伺服器,直接雙擊執行,工具->網路除錯工具,內容區點選右鍵,檢視Tcp引數,可以看到MaxUserPort是5000,右鍵還有個“設定最大Tcp”把各個引數值設定為最優。無需重啟,直接生效。

碼神工具也可以在這裡下載,http://x.newlifex.com/XCoder_Install.exe

碼神工具原始碼:https://github.com/NewLifeX/XCoder

 

安裝.NET Core執行時

.NET Core 3.1.6 也需要拷貝上去安裝,或者直接從 http://get.dot.net 下載。伺服器網路非常快。

 

網絡卡設定

為了增加每臺測試端的連線數,我們需要用netsh命令增加IP地址。這些IP地址來自於ECS設定的輔助私網IP。請一定要申請輔助私網IP以後再去設定網絡卡,未申請的IP地址可能出問題,第一次購買的002就是這樣殘廢了。

 

設定主網絡卡輔助私網IP

 

設定彈性網絡卡輔助私網IP

NetBench002

netsh interface ip add address "乙太網" 172.19.18.73 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.75 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.76 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.77 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.78 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.79 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.80 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.81 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.82 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.83 255.255.0.0 172.19.19.253

netsh interface ip add address "乙太網 2" 172.19.18.74 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.84 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.85 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.86 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.87 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.88 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.89 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.90 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.91 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.92 255.255.0.0 172.19.19.253

netsh interface ip add dns name="乙太網" addr=100.100.2.136
netsh interface ip add dns name="乙太網" addr=100.100.2.138

netsh interface ip add dns name="乙太網 2" addr=100.100.2.136
netsh interface ip add dns name="乙太網 2" addr=100.100.2.138

 

NetBench005

netsh interface ip add address "乙太網" 172.19.18.53 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.55 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.56 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.57 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.58 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.59 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.60 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.61 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.62 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網" 172.19.18.63 255.255.0.0 172.19.19.253

netsh interface ip add address "乙太網 2" 172.19.18.54 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.64 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.65 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.66 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.67 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.68 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.69 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.70 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.71 255.255.0.0 172.19.19.253
netsh interface ip add address "乙太網 2" 172.19.18.72 255.255.0.0 172.19.19.253

netsh interface ip add dns name="乙太網" addr=100.100.2.136
netsh interface ip add dns name="乙太網" addr=100.100.2.138

netsh interface ip add dns name="乙太網 2" addr=100.100.2.136
netsh interface ip add dns name="乙太網 2" addr=100.100.2.138

 

測試程式準備

我們採用網路庫例程來充當測試程式。

服務端,https://github.com/NewLifeX/NewLife.Net/tree/master/EchoTest

客戶端,https://github.com/NewLifeX/NewLife.Net/tree/master/Benchmark

原始碼在這裡有詳細講解

此處為語雀文件,點選連結檢視: https://www.yuque.com/go/doc/8990258

 

二者都需要Release編譯,以減少除錯日誌輸出。

為了減少記憶體佔用,我們需要修改配置檔案`Config\Socket.config`,把緩衝區大小從64k改為1k

<?xml version="1.0" encoding="utf-8"?>
<Socket>
  <!--網路除錯-->
  <Debug>false</Debug>
  <!--會話超時時間。預設20*60秒-->
  <SessionTimeout>7200</SessionTimeout>
  <!--緩衝區大小。預設64k-->
  <BufferSize>1024</BufferSize>
</Socket>

服務端客戶端都要修改這個配置,否則記憶體佔用過大。

 

我們選定001作為主伺服器,內網IP是172.19.18.4,拷貝EchoTest到伺服器目錄,雙擊跑起來,執行模式選擇1,服務端,開始監聽1234埠。

002~006作為測試端,配置環境後,拷貝Bench到伺服器目錄,開啟cmd,輸入一下命令跑起來(以005為例):

netbench.exe -c 1000000 -n 1000 -i 30000 -b 172.19.18.53-72 tcp://172.19.18.4:1234

各引數解讀如下:

  • -c 1000000,表示100萬併發,也就是100萬個tcp連線。003/004只有10個私有IP,這裡最高只能10*5w=50w
  • -n 1000,每個連線收發1000次資料;
  • -i 30000,兩次收發資料之間間隔30秒;
  • -b 172.19.18.53-72,發起連線時,繫結本地IP地址172.19.18.73到172.19.18.72,這些IP會均攤前面的100萬
  • tcp://172.19.18.4:1234,指定目標服務端的協議地址和埠

 

00:45達到100萬長連線

003和004各自貢獻了50萬連線,它們只有10個IP。

服務端在0點45分達到100萬線上,非常穩定,服務端和客戶端沒有出現任何錯誤。CPU和記憶體佔用也很好。

最後這張網路圖可以看到,前面測試百萬連線是,增長很快,實際上導致了部分連線失敗(<0.01%),後來加上引數控制了連線速度,才有穩步爬坡。

 

01:19突破200萬長連線

在003/004達到100萬長連線並維持30分鐘後,先後開啟005和002,預期朝著300萬方向走。

在1點19分左右,突破200萬長連線。此時,CPU和記憶體的壓力都很大,部分測試機的連線開始斷開。

經檢查,主伺服器記憶體不足,導致處理能力變弱,少量客戶端認為連線超時,執行自動重連,讓伺服器壓力加大,形成雪崩。

 

總結

超量完成了預期目標,100萬=>200萬。如果這次選擇48G或96G記憶體作為主伺服器,也許真有可能上300萬長連線。

2017年做的2266萬tps吞吐量測試

此處為語雀文件,點選連結檢視: https://www.yuque.com/go/doc/10610986

 

8月2日上午再戰300萬

購買12C96G高配例項,杭州區便宜,編號NetBench007

IP設定

netsh interface ip add address "乙太網" 172.16.188.92 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網" 172.16.188.94 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網" 172.16.188.95 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網" 172.16.188.96 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網" 172.16.188.97 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網" 172.16.188.98 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網" 172.16.188.99 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網" 172.16.188.100 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網" 172.16.188.101 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網" 172.16.188.102 255.255.240.0 172.16.191.253

netsh interface ip add address "乙太網 2" 172.16.188.93 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網 2" 172.16.188.103 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網 2" 172.16.188.104 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網 2" 172.16.188.105 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網 2" 172.16.188.106 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網 2" 172.16.188.107 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網 2" 172.16.188.108 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網 2" 172.16.188.109 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網 2" 172.16.188.110 255.255.240.0 172.16.191.253
netsh interface ip add address "乙太網 2" 172.16.188.111 255.255.240.0 172.16.191.253

netsh interface ip add dns name="乙太網" addr=100.100.2.136
netsh interface ip add dns name="乙太網" addr=100.100.2.138

netsh interface ip add dns name="乙太網 2" addr=100.100.2.136
netsh interface ip add dns name="乙太網 2" addr=100.100.2.138

 

準備就緒

 

先來一個億熱身

開啟100個併發連線,每個密集請求100萬次,輕輕鬆鬆得到 130萬tps 的吞吐

使用IPv6會更強一點

 

正式開始

本機壓測命令

netbench.exe -c 1000000 -n 10000 -i 60000 -b * tcp://127.0.0.1:1234

其中`-b *`表示繫結本機所有IP地址。

3分鐘輕鬆上100萬

由於沒有控制連線速度,期間有小量連線失敗。控制檯那裡有日誌時間,同時可以看到客戶端服務端連線數一致。

我們等它穩定一段時間,再去準備更多伺服器

從11:40開始,截止現在14:16,持續兩個半小時。建立999742個連線,現存也是999742,最大值999743說明中途有一個連線斷開,但是重連成功了。

 

增加測試機資源

再買5臺同樣配置伺服器,編號NetBench008~NetBench012

開始配置NetBench008,每次打命令太要命了,我們給碼神工具增加一個批量設定IP的功能。

從阿里雲ECS控制檯把輔助私網IP複製過來,點選“設定IP”,即可把這些IP地址設定到網絡卡上。

杭州區伺服器的網路限制很嚴格(可能別的區也這樣),在哪張網絡卡上申請的IP地址,只能設定到這張網絡卡上。即使每臺伺服器有兩張網絡卡,也不能把各自的輔助私網IP設定錯了,否則無法使用。

 

15:51達到300萬長連線

服務端程序佔用記憶體15G

 

15:54達到400萬長連線

伺服器0核4核爆滿

15:56作業系統直接掛了,自動重啟,連線數峰值404萬。

 

吞吐率壓測

5臺測試機,每臺向服務端建立100個連線,每個連線傳送100萬個訊息,每個端平均速度170萬tps

服務端總速度 170萬*5=1050萬tps

CPU很滿,網絡卡PPS太高