网络编程大并发实战-C100K

上篇进行了一个C10K的实战,并得到了一个初步的测试数据来支撑C10K的结果,那么本篇我们进行一个升级版C100K的实战。

对此我们还是使用之前的xlink 库,测试下epoll 及aio 的性能能否达到我们续期,C100K。

epoll

对于C100K问题,首先我们要解决的不是程序问题,而是系统设置问题,连接数的限制,文件句柄的限制,同时,对于客户端来说,由于单个IP端口数的限制,端口是16位的其最大端口数为 2的16次方全部利用起来也就只能支持60K多的连接(如果是土豪有很多测试机器可以当客户端端口限制基本可以忽略,不够测试就堆机器吧)针对如上问题解决如下:

句柄问题:

1.修改/etc/security/limits.conf (改为1024000 <NR_OPEN是为之后 1M问题做准备),

* soft nofile 1024000
* hard nofile 1024000

 

2.修改/etc/sysctl.conf:

fs.file-max = 1048576

[root@localhost ~]# sysctl -p
端口问题(客户端):

将可用端口全部开放,设置/etc/sysctl.conf:

net.ipv4.ip_local_port_range = 1024 65535

的只这样还是不够C100K,所以还需要多加几块网卡,或者添加虚拟地址。好吧咱就用最实惠的方式加虚拟IP吧。

还有一些TCP参数调优的东西,C100K就不列了,毕竟也就是个初步测试,主要是检验下实战代码的,咱就略了,等到C1M再说。

环境还是同前述,就直接来看看结果吧:

连接数 102399 注册数 102399
连接耗时
(ms)
2893 注册耗时
(ms)
6563

结论:C100K在3秒左右就轻松解决,而且该机器性能一般,同时该C100K全部活跃的QPS测试出来大致达到了20K/S。所以C100K中有20K的活跃度都是轻松搞定。

本来还想拿去年写的IOCP 压一下出个结果,看来还是放到接下来的C1M问题去试试吧,C100K应该完成没压力。(主要原因是懒,还没想好把IOCP跟xlink 合并在一起)。就先这样吧,C100K这种对于当前金融公司的产品应该完全够用了,基本都不需要分布式了,当然对于像淘宝这种有大客户体量的公司来说,只是C100K是不够的。接下来就试试C1M吧。

网络编程大并发实战-C10K

网络通信是由用户需求推动,早期,大家都玩单机游戏,上个互联网有个上百人就算是比较大型应用,当时并没有那么大的需求。但是,随着PC普及,互联网的爆发期,游戏经历单机,到局域网,到互联网多人大型游戏;互联网的发展也从1.0的浏览下网页,到2.0的各种社群交互互动,C10K问题首先涌现。

问题

早期的IO模型基本都是一个进程或者一个线程一个连接,C10K,物理资源是他的天花板。不管是否分布式,那都是及其耗费物理资源,成本巨大。

分析

既然问题是由于进程或者线程引起的物理资源问题,那么突破口也资源这里,IO线程模型使用就是让一个进程或者线程处理多个连接,网络IO就使用多路复用。在早期由一个比较成熟的就是select 模型,而后又发展出了poll,epoll,同时还有aio,这些在前面章节都有涉及,在这里我们就直接上代码来验证他们能否解决C10K问题,并进行分析。在此我们通过写一个简单的网络库,来验证各种实现方式模型是否可行。简单就叫其link吧。使用reactor 模式,该库包含select,poll,epoll等。线程模型为单线程接受处理,单线程接受多线程处理通信两种方式。统一level_tringer触发,统一处理成事件回调模式。通过测试对比每种实现方式来看看是如何解决C10K,及其中的一些问题及奥秘的。

select

在 linux 下使用select 有诸多连接限制,并且修改麻烦,同时 select 模型 在windows 也是参照linux下的select 模型移植过来的,并且windows 下只要重新定义 FD_SETSIZE 大小就可以改变原来 每个 接收所以就在本机windows 下测试。

逻辑:建立完成所有连接后,所有连接同时发送一个业务注册包,服务收到后立马应答。

客户端发送10239个链接,服务端稳定的接收了该10239个连接并注册成功,但是其响应时间有点延迟:

结果:内存占用连接数10239 大概100M,CPU 0- 5%的波动。

连接数 127 1023 10239 注册数 128/128 1023/1023 10239/
10239
连接耗时(MS) 23 179 4230 注册耗时
(MS)
16 36 7590

测试环境:以上测试数据在两台局域网的PC机器中进行,i5双核4线程,8G内存,其中还开了其他应用不是非常纯净,服务器测试程序开了1个连接接收线程,4个连接处理线程。

分析:同时测试服务器应该还有可改进的空间,为了能把select ,epoll等所有模型都放到LINK 库中,回调嵌套太多,内存拷贝等还有很多可优化,同时服务器调优下。所以如果再认真点做好,windows 下的这个 非阻塞 select 模型C10K 都应该不是问题,至少连接上,可以处理,但是发包应答的延迟还是挺致命的,有机会后续可以优化看看,那么如果直接使用windows提供的eventselect 模型应该更加容易达成这个结果了。当然这个结果已经出乎意料,linux 下的select 没有试过,但是windows下的这个结果,

结论:select模型下,初略估算C10K的连接,每秒2000的活跃连接并发还是能轻松支持。

epoll

架构模型同上面的,在做这个测试之前我们其实已经知道epoll 是高效能的,所以100,1000级别的咱就没必要测试了,直接看下 C10K的测试结果

结果:内存占用连接数10239 大概79M,CPU 0- 5%的波动。

连接数 10239 注册数 10239
连接耗时(ms) 469 注册耗时
(ms)
454
测试环境:Intel(R) Xeon(R) CPU E5-2430 0 @ 2.20GHz,4核,8G内存,测试服务器非常不纯净,将就用,服务器测试程序开了1个连接接收线程,4个连接处理线程。
结论:还是非常轻松的就能支持C10K连接,并且并发轻易上20K。

总结:

改测试库写的非常仓促,还是有很多改进空间。如果只是需要C10K的连接数的话,select 跟epoll 都能满足需求,就目前测试情况来看,select 也没有传说中的不稳定,还是挺稳定,但是select 并活跃并发数虽然也能上到 10K,但是其相应时间应该已经超出了正常业务场景的需求,所以如果并发数量不多,使用select 也能一战,这也是为什么以前的游戏服务器,虽然 epoll ,IOCP已经成熟的情况下,select 还是能撑起半壁江山,也是不无道理。所以如果要上生产大并发的话,epoll 还是不二选择。