在平常的交流中經常有人問.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的連接數,如果你的內存資源足夠看能沖到多少,別忘了把結果分享出來.