在平常的交流中經常有人問.net socket能支援多少線上?和C++或linux下比起來應該差很遠吧?其實產生這樣問題的主要原因是.net很少人去做這方面的測試,而在linux下則經常聽到什麼100w或500w線上連線的測試.這樣一個數字看起來多麼地讓人興奮...其實在這幾年編寫通訊服務的過程中已經意識到連線數的多少對整體影響並不大,主要歸功於現有成熟悉的網路模型和硬體資源.為了更進一步證實這個問題,所以打算在.NET下測試一下100w連線互動情況,不過由於硬體記憶體不足不能進行100W連線量,因此只能跑個50W線上的效果.
測試硬體數量有限和IP埠的限制,為了滿足這一次的測試需要只好一臺機上新增多個IP...
給測試的Client電腦新增了10個IP,每個IP分別繫結10000-60000埠,而測試程式針對每個IP構建一個執行緒來建立連線,連線建立完成後就定量輪循連線向伺服器傳送訊息.
測試程式
static void Connect(object state)
{ string ipaddress = (string)state; System.Net.IPAddress ip = System.Net.IPAddress.Parse(ipaddress); for(int i=10000;i<60000;i++) { try { Socket mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); mSocket.Bind(new System.Net.IPEndPoint(ip, i)); mSocket.Connect(mHost, mPort); SocketAsyncEventArgs sae = new SocketAsyncEventArgs(); sae.SetBuffer(new byte[1024], 0, 1024); sae.UserToken = mSocket; sae.Completed += OnReceive; BeginReceive(mSocket, sae); lock (mSockets) { mSockets.Add(mSocket); } } catch (Exception e_) { Console.WriteLine("create socket client error {0} with {1}@{2}", e_.Message, ipaddress, i); } System.Threading.Thread.Sleep(1); } while (true) { for (int i = 0; i < 20; i++) { long index = System.Threading.Interlocked.Increment(ref mIndex); mSockets[(int)(index % mSockets.Count)].Send(Encoding.UTF8.GetBytes("{\"name\":\"henryfan\"}")); } System.Threading.Thread.Sleep(1); } }
程式碼程式比較簡單,每次獲取20個連線進行資料傳送,每次傳送完後sleep一次,這樣主要是為了防止資源被用光導致測試無法進行;畢竟這一次的測試是以連線數量為基準.
測試結果
整個測試結果和我想的沒有多大的出入,構建50W連線後由於資料互動量不大,所以除了佔用比較多的記憶體以外基本沒有對伺服器CPU構成壓力.
50W連線整個互動大概是每秒1.2w的請求應答量.由於連線太多在超過十幾W連線的情況下netstat已經無法正常顯示該埠對應的連線數量了....;雖然連線數量比較多但程式所佔用的CPU資源並不高
CPU的平均佔用率大概在7%左右.
服務端的記憶體佔用率大概在2.6G左右,實際作業系統的記憶體已經滿了.
總結
由於記憶體的限制在這些測試中不能跑到100w個連線有點可惜(不過以後閒著的時候把記憶體加上去後還會無聊地再刷一次)...;從結果已經可以進一步說明了一個非常重要的問題,只從連線數上來衡量一個服務的能力是沒有多大意義.只有請求應答量才能體現出服務端的效能優勢.所以當你看到100W連線的測試文章不感到驚歎,畢竟請求應答量才是體現性以指數.如果有興趣的同學其電腦記憶體資源充足的情況可以做出更高的連線數出來,為了方便測試便順提供測試程式.
/files/file/20140907/20140907145550_4695.rar
從windows的配置表資訊來看,最大連線數是1K多W的連線數,如果你的記憶體資源足夠看能衝到多少,別忘了把結果分享出來.