freeeyes 发表于 2009-12-8 15:16:31

ACE_Dev_Poll_Reactor模型下的最大并发连接数

我在linux下使用reactor下的ACE_Dev_Poll_Reactor()模型。
但是却遇到了一个问题,我写了一个测试程序,创建了2000个socket去连接这个服务器。结果在连接达到大约1000个的时候,服务器处理连接速度明显变慢。并在接受数据包的时候抛出异常,我捕捉到了异常并打印了下来
ConnectID = 1003, recv data is error nDataLen = [-1] errno = Error = .
我一开始查询资料,以为是在linux下的I/O连接限制造成的,于是我ulimit -n 65535,修改了对进程下的I/O操控限制。
但是问题依旧。
我以前使用ACE_Select_Reactor模型的时候,也遇到过这样的问题,后来知道是因为select限制造成的,修改了ACE的编译文件配置参数,但是我知道select模型超过1024个以后效率会打折扣。于是放弃了这个模型(自己做了一个大并发的客户端测试,时间相应确实不理想,2000个链接)。
ACE_Dev_Poll_Reactor()和ACE_TP_Reactor()应该都是基于epoll的吧,我以前也写过epoll的模型,我印象中链接是和Win下的iocp类似(IOCP是支持内核级别的异步IO调度,而epoll似乎只是一种模拟,还不能称之为完全的异步IO。但是ACE本身的Proactor目前完整支持Win下的IOCP,但是ACE_POSIX_Proactor却在Linux下不是完整的 支持,虽说能打上aio的补丁,但是aio本身也不是内核级别的支持。)
所以我想请教大家,ACE_Dev_Poll_Reactor是否像select模型一些样存在链接限制?
这个问题Timer expired,我在百度和goole上查询了很久,似乎没有什么满意的答案。想问造成这个现象的原因?是什么呀?
呵呵,想找一个对ACE研究的群,却找到了这里。请教大家了。

modern 发表于 2009-12-11 08:53:58

这里是本版的群http://www.acejoy.com/bbs/viewthread.php?tid=216&extra=page%3D1

ACE_Dev_Poll_Reactor默认是使用poll,
使其支持epoll需要在config_linux.h里添加这个语句#define ACE_HAS_EVENT_POLL
并重新make,make install
ACE_TP_Reactor默认使用的是Select。

freeeyes 发表于 2010-1-18 11:59:14

我已经找到原因,问题不在链接。
首先和linux下的IO设置有关,要设置一下 ulimit -n 看看当前允许的链接上线并予以设置。
经过反复测试发现,Devpoll在1007个链接以后,recv的时候会有一些延迟,问题就出现在这里。
我的代码如下:
ACE_Time_Value nowait(ACE_Time_Value::zero);
int nDataLen = this->peer().recv(m_RecvPacket.WritePtr(), nCurrRecvSize, MSG_NOSIGNAL, &nowait);
改成
ACE_Time_Value nowait(5);
int nDataLen = this->peer().recv(m_RecvPacket.WritePtr(), nCurrRecvSize, MSG_NOSIGNAL, &nowait);
问题就解决了。
究其本质,跟踪了ACE的源码,ACE_Time_Value::zero和0是不一样的。ACE_Time_Value::zero代表不等待。0代表无限等待。这两个是有本质区别的。<ACE陷阱>里面有关于这个问题的描述。

ctlovexb 发表于 2010-11-12 12:31:27

回复 3# freeeyes


   我也遇到这样的问题,ACE_Dev_Poll_Reactor下连接数达到1000多时,服务器处理连接速度很满。请教版主如何解决的?

freeeyes 发表于 2010-11-12 15:21:08

我觉得分为两部分处理。
1是提高linux下的链接上限。上面已经给出。
2是增加reactor下的反应器,如果反应器只有一个是比较慢。多反应器绑定一个端口。

ctlovexb 发表于 2010-11-17 10:34:22

回复 5# freeeyes


    你好,你说的多反应器绑定一个端口是不是可以理解为多线程的反应器,我用的多线程运行ACE_Dev_Poll_Reactor的run_event_loop,在同样的情况下效率也没提升,连接限制已经修改,2000连接处理时间就很长,内存消耗也很大。我也看到你的服务器的例子,你的接受端初始化时是不是运用内存池提前生成很多句柄,减少连接建立时创建句柄的时间呢?

freeeyes 发表于 2010-11-17 10:48:09

我的理解是,epoll本身是同步服务器。
在处理大量链接的时候,握手的时间是必要的时间消耗。
有几种处理方法,我正在新版上进行尝试。
第一个你已经看到了,我使用了内存池,减少了new和delete操作。
我现在正在尝试,绑定的时候启动多reactor反应器来处理accept。效果现在还不错,性能比较快。这一点也借鉴了陈硕的那个服务器,但是在处理数据锁的时候,需要花费些细心。
本质提升速度无外乎两部分,第一减少IO的调用,第二,采用多线程去处理大量链接涌入请求。
我觉饿得处理好这两点,基本也就能达到一定效果了。

ctlovexb 发表于 2010-11-17 16:24:13

多谢版主,继续研究,以后请多指教啊,ACE新手!
页: [1]
查看完整版本: ACE_Dev_Poll_Reactor模型下的最大并发连接数