在平常的交流中经常有人问.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连接的测试文章不感到惊叹,毕竟请求应答量才是体现性以指数.如果有兴趣的同学其电脑内存资源充足的情况可以做出更高的连接数出来,为了方便测试便顺提供测试程序.
从windows的配置表信息来看,最大连接数是1K多W的连接数,如果你的内存资源足够看能冲到多少,别忘了把结果分享出来.