SPServer: 一个基于线程池(包括HAHS和LF)的开源服务器框架
时间:2008-01-16 11:14:26 来源: 作者:
|
SPServer 是一个实现了半同步/半异步(Half-Sync/Half-Async)和领导者/追随者(Leader/Follower) 模式的服务器框架,能够简化 TCP server 的开发工作。 SPServer 使用 c++ 实现,目前实现了以下功能: 1.封装了 TCP server 中接受连接的功能; 2.使用非阻塞型I/O和事件驱动模型,基于 libevent; 3.对于 HSHA 线程池,由主线程负责处理所有 TCP 连接上的数据读取和发送,因此连接数不受线程数的限制;主线程读取到的数据放入队列,由一个线程池处理实际的业务; 4.对于 LF 线程池,由线程池中的线程轮流获得 leader 角色进行处理; 5.一个 http 服务器框架,即嵌入式 web 服务器。 6.从 0.7 版本开始支持 ssl 。 项目主页 [url=http://code.google.com/p/spserver/]http://code.google.com/p/spserver/ 下载地址 [url=http://freshmeat.net/redir/spserver/68862/url_tgz/spserver-0.3.src.tar.gz]http://spserver.googlecode.com/files/spserver-0.6.src.tar.gz [url=http://code.google.com/p/spserver/downloads/list]http://code.google.com/p/spserver/downloads/list 详细的介绍 [url=http://iunknown.javaeye.com/blog/59804]http://iunknown.javaeye.com/blog/59804 HSHA 模式 [url=http://www.cs.wustl.edu/~schmidt/PDF/HS-HA.pdf]http://www.cs.wustl.edu/~schmidt/PDF/HS-HA.pdf LF 模式 [url=http://www.cs.wustl.edu/~schmidt/PDF/lf.pdf]http://www.cs.wustl.edu/~schmidt/PDF/lf.pdf 关于 HSHA 和 LF 的一些介绍 [url=http://iunknown.javaeye.com/blog/60414]http://iunknown.javaeye.com/blog/60414 项目中包含一个线程池子项目 http://iunknown.javaeye.com/blog/38544 [ 本帖最后由 iunknown 于 2007-8-11 13:36 编辑 ] converse 回复于:2007-07-04 20:32:49 小声的说,LZ的博客在我家FF的链接中保存着.... iunknown 回复于:2007-07-05 13:20:16 引用:原帖由 converse 于 2007-7-4 20:32 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7006900&ptid=957813]
小声的说,LZ的博客在我家FF的链接中保存着.... 多谢!你这样说,我很大压力啊。。。。。:) 关于 HSHA , LF 线程池,还有 reactor ,proactor 这些模式,目前能找到的参考实现有 ACE 和 twisted 。 不知这里有没有人做过类似的框架?或者有没有人希望使用这样的框架?希望能获得大家的建议,继续完善。 [ 本帖最后由 iunknown 于 2007-7-5 13:21 编辑 ] iunknown 回复于:2007-07-06 13:48:32 在 [url=http://code.google.com/p/spserver/]SPServer 中实现了 HSHA 和 LF 两种线程池。 目前的实现还是比较可读的,这两种线程池最主要的处理逻辑各自都被集中到了一个函数中。 先来看看 HSHA 的核心实现代码 http://spserver.googlecode.com/svn/trunk/spserver.cpp
一些细节都被去掉了。从这段代码可以看到,HSHA 的处理流程是: 1.运行 start 函数的线程称为 event_loop 线程,负责 recv/send 。 所有的 recv/send 都在 event_base_loop 这个函数调用上完成的。 这个层就是属于异步层。 2. event_base_loop 在 recv 的时候,会调用 MsgDecoder.decode 函数, 如果 decode 返回 OK ,说明完整地读入数据了,那么就把对应的数据放入 eventArg.mInputResultQueue 里面。 在 send 的时候,如果把一个 Message 完整地发送了, 那么就把这个 Message 放入 eventArg.mOutputResultQueue。 这两个就是队列,队列里面保存的数据一般称为完成事件。 3.workerExecutor 和 actExecutor 就是同步层。 由于完成事件的处理可能会涉及很复杂的处理,可能会使用到数据库或者其他, 因此不能直接使用 event_loop 线程,而是使用线程池。 这个就是同步层。 再来看 LF 的核心代码 http://spserver.googlecode.com/svn/trunk/splfserver.cpp
在 run 函数中,启动线程池中的多个线程运行 lfHandler , 由 lfHandler 不断地运行 handleOneEvent 。 线程的角色转变在上面的注释中可以很清楚地看到。 由于这里的实现比较简单,LF 线程池的线程都是预先创建的, 并且没有实现线程池之外的线程可以加入的功能, 所以在 leader 切换为 worker,并且提升一个 follower 为 leader 的时候, 只需要用一个 mutex 就可以解决了。 ruchong 回复于:2007-07-06 14:32:25 下了编译不过. localhost spserver-0.6 # make gcc -Wall -D_REENTRANT -D_GNU_SOURCE -g -fPIC -I../libevent/ -c event_msgqueue.c -o event_msgqueue.o event_msgqueue.c:18:20: error: config.h: No such file or directory In file included from event_msgqueue.c:19: event_msgqueue.h:15:19: error: event.h: No such file or directory In file included from event_msgqueue.c:19: event_msgqueue.h:24: warning: ‘struct event_base’ declared inside parameter list event_msgqueue.h:24: warning: its scope is only this definition or declaration, which is probably not what you want event_msgqueue.c:37: error: field ‘queue_ev’ has incomplete type event_msgqueue.c:161: warning: ‘struct event_base’ declared inside parameter list event_msgqueue.c:161: error: conflicting types for ‘msgqueue_new’ event_msgqueue.h:24: error: previous declaration of ‘msgqueue_new’ was here event_msgqueue.c: In function ‘msgqueue_new’: event_msgqueue.c:187: warning: implicit declaration of function ‘event_set’ event_msgqueue.c:187: error: ‘EV_READ’ undeclared (first use in this function) event_msgqueue.c:187: error: (Each undeclared identifier is reported only once event_msgqueue.c:187: error: for each function it appears in.) event_msgqueue.c:187: error: ‘EV_PERSIST’ undeclared (first use in this function) event_msgqueue.c:188: warning: implicit declaration of function ‘event_base_set’ event_msgqueue.c:189: warning: implicit declaration of function ‘event_add’ event_msgqueue.c: In function ‘msgqueue_destroy’: event_msgqueue.c:202: warning: implicit declaration of function ‘event_del’ make: *** [event_msgqueue.o] Error 1 清汤挂面 回复于:2007-07-06 15:26:29 引用:原帖由 iunknown 于 2007-7-5 13:20 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7009867&ptid=957813]
多谢!你这样说,我很大压力啊。。。。。:) 关于 HSHA , LF 线程池,还有 reactor ,proactor 这些模式,目前能找到的参考实现有 ACE 和 twisted 。 不知这里有没有人做过类似的框架?或者有没有人希 ... I've done the reactor service frame iunknown 回复于:2007-07-06 19:26:06 引用:原帖由 ruchong 于 2007-7-6 14:32 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7016219&ptid=957813]
下了编译不过. localhost spserver-0.6 # make gcc -Wall -D_REENTRANT -D_GNU_SOURCE -g -fPIC -I../libevent/ -c event_msgqueue.c -o event_msgqueue.o event_msgqueue.c:18:20: error: config.h: No suc ... 请阅读 [url=http://spserver.googlecode.com/svn/trunk/README]README 文件,请先检查是否安装了 libevent,确认安装之后,修改 Makefile 指定 libevent 的路径。 引用: 2.Building Before building spserver, libevent must been installed. Test with libevent 1.1 and 1.2. You can donwload libevent from its home page: http://www.monkey.org/~provos/libevent/ Edit spserver/Makefile to specify the path of libevent: LIBEVENT_INCL = -I<path_to_libevent_include> LIBEVENT_LIB = -L<path_to_libevent_library> -levent [ 本帖最后由 iunknown 于 2007-7-6 19:53 编辑 ] iunknown 回复于:2007-07-06 19:41:57 引用:原帖由 清汤挂面 于 2007-7-6 15:26 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7016559&ptid=957813]
I've done the reactor service frame reactor 是按 ACE 的接口来实现,还是按 libevent 的接口来实现? ACE 使用的是 OO 的接口,libevent 使用的是 C 的 callback 。 ACE 基于 OO 的接口
libevent 基于 C 的 callback 的接口
fn 就是 calback,通常的实现类似
libevent 的实现方式,其实类似于 《unix网络编程》 (第二版,中文版) Page 141 和 Page 148 的代码。可以看看这里的说明:http://iunknown.javaeye.com/blog/41077 一般情况下,如果业务处理逻辑不涉及过多的 IO 操作,使用单线程运行reactor 的效果是非常好的。比如 memcached 在 1.2 之前的版本就是单线程运行 libevent 实现的,性能非常好。在 memcached 中只有网络请求和响应是 IO 操作,内部的处理逻辑只是 HASH 表的查找和维护,不会造成阻塞,因此使用单线程是完全没有问题的。 但如果业务处理逻辑还涉及很多其他的 IO 操作的话,那么或者把这些 IO 操作也纳入 reactor 的控制,要么就需要使用多线程了。但在某些情况下,业务中涉及的 IO 操作是类似数据库查询这样的 IO 操作,这些 IO 操作很难纳入 reactor 的控制,就要使用多线程了。 [ 本帖最后由 iunknown 于 2007-7-6 19:49 编辑 ] NewCore 回复于:2007-07-06 22:09:25 学习一下设计思路. iunknown 回复于:2007-07-07 09:10:11 在 SPServer 中自带了几个使用 SPServer 框架实现的 demo :testecho.cpp ,testsmtp.cpp , testchat.cpp ,testhttp.cpp 。 testecho.cpp 是 echo 服务器。http://spserver.googlecode.com/svn/trunk/testecho.cpp testchat.cpp 是 chatroom 服务器。http://spserver.googlecode.com/svn/trunk/testchat.cpp testsmtp.cpp 是 fake smtp 服务器。http://spserver.googlecode.com/svn/trunk/testsmtp.cpp testhttp.cpp 是 echo http 服务器,把接收到的 http 请求解释出来,把请求的信息输出为一个 html 返回。 http://spserver.googlecode.com/svn/trunk/testhttp.cpp echo 服务器和 chatroom 服务器应该是很多学网络编程的人完成的第一个完整的应用程序。 使用 SPServer 框架实现的这两个服务器,主要的特点就是开发者(指框架的使用者,不是框架的实现者)只需要处理内存对象,而不需要处理网络 IO ,所有的网络 IO 都由 SPServer 框架来处理。在 echo 这种相对比较简单的服务器上,对开发者屏蔽网络 IO 带来的好处可能不见的很大,但是对于 chatroom 这类相对复杂的服务器,对开发者屏网络 IO 就可以带来很大的好处,开发者可以专住于实现 chatroom 的业务逻辑,开发者所面对的都是内存对象。 testsmtp.cpp 主要是用来演示对于 smtp 这样的协议,SPServer 是怎么支持的。testsmtp 实现的是一个空的 smtp 服务器,能够完成标准的 smtp 应答,不过实际上内部什么事都没干,:) 以上这些 demo 都可以使用自带的 teststress 测试 工具来做压力测试。
testhttp.cpp 是一个 echo http 服务器。可以使用 apache 自带的 ab 工具对 testhttp.cpp 进行测试。 引用: bash-2.05a$ ./testhttp -s lf -t 1 bash-2.05a$ ./ab -n 10000 -c 100 -k http://127.0.0.1:8080/ Requests per second: 4576.40 [#/sec] (mean) [ 本帖最后由 iunknown 于 2007-7-7 09:23 编辑 ] queue 回复于:2007-07-10 13:04:04 引用:原帖由 iunknown 于 2007-7-6 19:41 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7017812&ptid=957813]
ACE 基于 OO 的接口
看了一下代码,SPServer 实现的不是类似 Event_Handler 这样的接口,而是
这个接口更类似 proactor ,而不是 reactor 。接口上体现的不是 event ,而是 result 。 iunknown 回复于:2007-07-10 19:39:21 引用:原帖由 queue 于 2007-7-10 13:04 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7030950&ptid=957813]
这个接口更类似 proactor ,而不是 reactor 。接口上体现的不是 event ,而是 result 。 不错,SPServer 其实更像 proactor 。之前在这里也讨论得到类似的结果 http://iunknown.javaeye.com/blog/post/320133 引用: 呵呵,这两天重新看 POSA2 关于 reactor/proactor 的论述,理解的更多了一点。对于 spserver ,我也有这种看法。 reactor 和 proactor 的主要区别: proactor 是由于异步操作的完成事件触发 handler 的执行,reactor 是由于产生了可以进行非阻塞操作的事件触发 handler 的执行。 libevent 可以说是一个 reactor 的实现。这一点通过对比 reactor 的 Event_Handler 和 libevent 的 callback ,可以和清楚地看到是非常类似的。两者在接口上,体现的是 IO 句柄是否可读或可写。 spserver 也就是相当于基于 libevent 的 reactor 封装了一个 proactor 出来。也是从对比 proactor 和的 Complete_Handler 和 SP_Handler 可以看出来。两者在接口上,体现的是异步操作的结果:proactor 是 Async_Result ,spserver 是 SP_Request->getMsgDecoder() 。 找到了一个用模拟 async IO 来实现 Proactor 的文章。 [url=http://www.artima.com/articles/io_design_patterns2.html]Comparing Two High-Performance I/O Design Patterns ACE 自带的 proactor 只能在支持异步 IO 的操作系统上才能使用,比如 windows 有 overlapped ,部分 unix 平台有 aio 。 这篇文章描述了如果使用 event-driven 来模拟异步 IO ,从而实现 proactor 模式。 在开发 SPServer 之前也曾看到过这篇文章,不过当时没留意,也没完全理解它的意思。后来经过讨论才发现 SPServer 的做法和它描述的做法非常相似。 queue 回复于:2007-07-11 13:19:06 引用: 找到了一个用模拟 async IO 来实现 Proactor 的文章。 Comparing Two High-Performance I/O Design Patterns ACE 自带的 proactor 只能在支持异步 IO 的操作系统上才能使用,比如 windows 有 overlapped ,部分 unix 平台有 aio 。 这篇文章描述了如果使用 event-driven 来模拟异步 IO ,从而实现 proactor 模式。 Comparing Two High-Performance I/O Design Patterns 这篇文章不错,有没有考虑过按照这篇文章所说的设计基于 libevent 来实现一个正宗的 proactor ?这篇文章提到的 TProactor 仍然依赖于 ACE ,如果基于 libevent 实现一个 proactor,应该算是一个轻量级的 proactor,应该还不错。 PS:不知道有没有人知道有另外的轻量级的 proactor 的实现? iunknown 回复于:2007-07-11 20:56:09 引用:有没有考虑过按照这篇文章所说的设计基于 libevent 来实现一个正宗的 proactor ?这篇文章提到的 TProactor 仍然依赖于 ACE ,如果基于 libevent 实现一个 proactor,应该算是一个轻量级的 proactor,应该还不错。 对于“正宗”的 ACE Proactor 接口怎么和线程池结合还没有搞得很清楚。ACE 自带的例子看得不是很明白。 找时间重新看看 ACE 的例子,期望能够看得明白些,到时再考虑是否实现一个“正宗”的 Proactor 。 就目前实现的这个“非正宗”的 Proactor ,主要的差距是使用者对于 Proactor 的操作受到比较多的限制,没有“正宗”的 Proactor 那么灵活。在 0.5 版本中加入了一个 Dispatcher 的类,部分地解决了这个问题,使得核心的线程池框架可以应用到 server socket ,也可以应用到 client socket 上。 [ 本帖最后由 iunknown 于 2007-7-11 20:59 编辑 ] queue 回复于:2007-07-13 13:11:29 引用:在 0.5 版本中加入了一个 Dispatcher 的类,部分地解决了这个问题,使得核心的线程池框架可以应用到 server socket ,也可以应用到 client socket 上。 看了一下 dispatcher 的例子,可以考虑在搞一个进程池 framework 出来,加上这个 dispatcher 就可以实现 apache 的 worker 模型了。按 apache 的做法,设定每个进程最多服务器的请求数,然后自动退出,依靠进程退出时自动回收资源,这样可以使得整个 framework 的稳定性非常好。 在这个论坛好像看到有不少人实现了进程池,不知道有没有人结合进程池和线程池做过实际的应用? iunknown 回复于:2007-07-18 21:56:40 引用:原帖由 queue 于 2007-7-13 13:11 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7048233&ptid=957813]
看了一下 dispatcher 的例子,可以考虑在搞一个进程池 framework 出来,加上这个 dispatcher 就可以实现 apache 的 worker 模型了。按 apache 的做法,设定每个进程最多服务器的请求数,然后自动退出,依靠 ... 有这样的想法,最近也做了一些 research,看了一些现有的 进程池 framework,包括 apache,fastcgi,tinycxx等,正在熟悉进程池 framework 的设计。 fastcgi 的一个实现 -- mod_fcgid ,里面的进程池实现得不错,可惜就是和 apache 结合的太紧密了,要单独抽离出来比较困难。 iunknown 回复于:2007-08-11 13:24:02 spserver 0.7 版本发布。这个版本最大的亮点是开始支持 ssl 。 1。spserver 中 socket 相关的操作被抽象为 IOChannel 层 2。ssl 的相关代码被实现为一个 plugin (libspopenssl.so),对于不需要使用 ssl 的用户,不需要引入 ssl 相关的头文件和库 3。原有的使用 spserver 实现的程序,不受影响。如果想使用 ssl 功能,那么只需要增加少数几行代码即可。 代码可以到主页下载:http://code.google.com/p/spserver/ 一个 echo 程序的例子 http://spserver.googlecode.com/svn/trunk/openssl/testechos.cpp
[ 本帖最后由 iunknown 于 2007-8-11 13:26 编辑 ] zsniper 回复于:2007-08-15 17:32:21 认真拜读LZ的blog。。。。。。 zsniper 回复于:2007-08-16 15:39:43 LZ能用C写一个这样的库吗? 我尝试着把它专成C的,呵呵。。。技术不够,还有好多没读懂哦。。。 iunknown 回复于:2007-08-16 20:04:49 引用:原帖由 zsniper 于 2007-8-16 15:39 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7217941&ptid=957813]
LZ能用C写一个这样的库吗? 其中的线程池部分开始是用纯 C 实现的。 http://iunknown.javaeye.com/blog/38544 如果要把 SPServer 移植到 C 上面,应该不是太难。 SPServer 很少用继承,大部分是采用基于对象范式(object-based paradigm)来实现的。 用基于对象的方式设计的类,可以很容易地用 struct + global function 来实现。 唯一的用了继承的地方是 SP_Handler ,但是这个 SP_Handler 全部是纯虚函数,也可以用一个包含多个函数指针的 struct 来替代。 不过我暂时没有计划移植到 C 上,暂时想进一步完善现有的代码。 iunknown 回复于:2007-08-22 22:33:07 在实现了 ssl 的支持之后,使用 spserver 来实现一个 ssl proxy ,就很简单了。 为 spserver 增加了一个名为 sptunnel 的可执行程序,这是一个通用的 TCP ssl proxy 程序。 通用的意思就是可以作为任何给予 TCP 协议服务器做 ssl proxy,比如 http、smtp、pop3 这类。 在最新的 0.8 release 中,重构了一下目录,分开了 spserver 最基本的功能和各个插件。 最新代码下载:http://spserver.googlecode.com/files/spserver-0.8.src.tar.gz sptunnel 的用法如下所示,默认侦听在 8080 端口,并转发到 google.com 。 运行之后,可以使用 IE 或者 firefox 来访问:https://<ip.of.sptunnel>:8080/
[ 本帖最后由 iunknown 于 2007-8-22 22:37 编辑 ] zsniper 回复于:2007-10-24 09:36:07 请问楼主,假如client主动关闭连接,spserver如何得知 还有为什么close(fd)关不掉socket zsniper 回复于:2007-10-28 19:39:00 请问楼主,是不是因为没有event_del(fd),close(fd)才不会激发FIN???? fengdays 回复于:2007-11-16 17:58:32 牛人,问个低级问题 编译出错,错误如下 event_msgqueue.c:125: error: previous definition of 'circqueue_pop_head' was here event_msgqueue.c:138: error: redefinition of 'msgqueue_pop' event_msgqueue.c:138: error: previous definition of 'msgqueue_pop' was here event_msgqueue.c:138: error: redefinition of 'msgqueue_pop' event_msgqueue.c:138: error: previous definition of 'msgqueue_pop' was here event_msgqueue.c:161: warning: "struct event_base" declared inside parameter list event_msgqueue.c:161: error: redefinition of 'msgqueue_new' event_msgqueue.c:161: error: previous definition of 'msgqueue_new' was here event_msgqueue.c:161: error: redefinition of 'msgqueue_new' event_msgqueue.c:161: error: previous definition of 'msgqueue_new' was here event_msgqueue.c: In function `msgqueue_new': event_msgqueue.c:187: error: `EV_READ' undeclared (first use in this function) event_msgqueue.c:187: error: `EV_PERSIST' undeclared (first use in this function) event_msgqueue.c: At top level: event_msgqueue.c:197: error: redefinition of 'msgqueue_destroy' event_msgqueue.c:197: error: previous definition of 'msgqueue_destroy' was here event_msgqueue.c:197: error: redefinition of 'msgqueue_destroy' event_msgqueue.c:197: error: previous definition of 'msgqueue_destroy' was here event_msgqueue.c:209: error: redefinition of 'msgqueue_push' event_msgqueue.c:209: error: previous definition of 'msgqueue_push' was here event_msgqueue.c:209: error: redefinition of 'msgqueue_push' event_msgqueue.c:209: error: previous definition of 'msgqueue_push' was here event_msgqueue.c:223: error: redefinition of 'msgqueue_length' event_msgqueue.c:223: error: previous definition of 'msgqueue_length' was here event_msgqueue.c:223: error: redefinition of 'msgqueue_length' event_msgqueue.c:223: error: previous definition of 'msgqueue_length' was here make: *** [event_msgqueue.o] 错误 1 这种错误应该是头文件包含上出错了吧,应该是头文件被包含多次吧? 我这用的是RedHat fc6 或者是否.c文件 gcc编译的问题呢?请指教一下!多谢!!:em03: iunknown 回复于:2007-11-17 21:23:01 引用:原帖由 zsniper 于 2007-10-24 09:36 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7503463&ptid=957813]
请问楼主,假如client主动关闭连接,spserver如何得知 还有为什么close(fd)关不掉socket 抱歉,很久没有来 CU 看看。 如果 client 主动关闭连接,那么先调用 SP_Handler::error ,然后调用 SP_Handler::close 。 spserver 认为 client 主动关闭连接是一种错误。通常设计良好的协议都会有一个 client 和 server 的协商关闭的指令。 在 spserver 中,通过 SP_Handler::handle 返回 -1 来指示 server 主动关闭连接。 close(fd) 关不掉 socket ?能说明一下上下文吧?是指在 spserver 中吗? [ 本帖最后由 iunknown 于 2007-11-17 21:24 编辑 ] iunknown 回复于:2007-11-17 21:29:45 引用:原帖由 fengdays 于 2007-11-16 17:58 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7601136&ptid=957813]
编译出错,错误如下 event_msgqueue.c:125: error: previous definition of 'circqueue_pop_head' was here event_msgqueue.c:138: error: redefinition of 'msgqueue_pop' event_ms ... 刚刚找了一台 RedHat FC 试了一下,没有问题,可以编译。请提供一下 gcc 的版本。 -bash-3.1$ gcc --version gcc (GCC) 4.1.2 20070626 (Red Hat 4.1.2-13) Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. -bash-3.1$ cat /etc/redhat-release Fedora Core release 6 (Zod) -bash-3.1$ uname -a Linux xxxxx 2.6.22.7-57.fc6 #1 SMP Fri Sep 21 19:45:12 EDT 2007 x86_64 x86_64 x86_64 GNU/Linux [ 本帖最后由 iunknown 于 2007-11-17 21:53 编辑 ] fengdays 回复于:2007-11-19 09:20:31 gcc --version gcc (GCC) 3.4.6 20060404 (Red Hat 3.4.6-8) Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. fengdays 回复于:2007-11-19 09:32:52 gcc --version gcc (GCC) 3.4.6 20060404 (Red Hat 3.4.6-8 ) Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. uname -a Linux Car-2 2.6.9-55.0.2.ELsmp #1 SMP Tue Jun 26 14:30:58 EDT 2007 i686 i686 i386 GNU/Linux cat /etc/redhat-release CentOS release 4.5 (Final) 晕啊,是CentOS啊, 唉! 原来不是FC! 服务器是维护部门安装的,我要求他们安装FC的啊,真晕! 这样的话是不是要更新一下gcc编译器版本啦? zsniper 回复于:2007-12-18 09:32:03 请问LZ,你的SP框架的服务器,是那种客户机请求,服务器相应的模式,那假如服务器主动广播,该如何使用你的这个框架呢~? 是不是再本地建立一个连接,好像GM一样 , 向在线的所有人广播? 还是直接创建一个广播task,压入input_queue中? [ 本帖最后由 zsniper 于 2007-12-18 09:50 编辑 ] zsniper 回复于:2007-12-18 09:42:33 引用:原帖由 iunknown 于 2007-11-17 21:23 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7603477&ptid=957813]
抱歉,很久没有来 CU 看看。 如果 client 主动关闭连接,那么先调用 SP_Handler::error ,然后调用 SP_Handler::close 。 spserver 认为 client 主动关闭连接是一种错误。通常设计良好的协议都会有一 ... 谢谢lz,是我犯了个低级错误,在testecho中定义了一个close()函数,结果程序在close(socket)的时候,调用的是我自己定义的这个close() 呵呵。。。 iceviewer 回复于:2007-12-18 09:54:58 :mrgreen: 学习中,谢谢啦 iunknown 回复于:2007-12-18 13:09:19 引用:原帖由 zsniper 于 2007-12-18 09:32 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7732992&ptid=957813]
请问LZ,你的SP框架的服务器,是那种客户机请求,服务器相应的模式,那假如服务器主动广播,该如何使用你的这个框架呢~? 是不是再本地建立一个连接,好像GM一样 , 向在线的所有人广播? 还是直接创建 ... SPServer 目前已经实现的广播功能是针对聊天室这种功能,在同一个聊天室中的各个 client 之间广播消息。 如果要实现服务器主动广播,目前来说只能使用你提到的“在本地建立一个连接,好像GM一样 , 向在线的所有人广播”。 采用这种方法,这个本地连接发送一个特殊的数据包过去,在 SP_Handler::handle 中识别出这个特殊数据包,从而触发广播事件。 zsniper 回复于:2007-12-18 13:24:40 恩。。。谢谢LZ,我想了一下也只有这种方式。。。 zsniper 回复于:2007-12-28 10:31:09 再次请问LZ,HAHS和LF,感觉都是那种高并发的服务器 ,感觉他的相应不是很快? iunknown 回复于:2007-12-28 23:31:21 引用:原帖由 zsniper 于 2007-12-28 10:31 发表 [url=http://bbs.chinaunix.net/redirect.php?goto=findpost&pid=7779163&ptid=957813]
再次请问LZ,HAHS和LF,感觉都是那种高并发的服务器 ,感觉他的相应不是很快? 之前曾经用 spserver 实现过一个类似 memcached 的 spcached ,测试结果如下 # 500000 sets: 229266ms 2173 次每秒 # 500000 gets: 284856ms 1754 次每秒 采用的是长连接。 具体的测试数据可以参考:http://iunknown.javaeye.com/blog/80095 刚刚又测试了短连接的情况,采用了测试 spprocpool 的方法。 spprocpool的测试结果:http://bbs.chinaunix.net/thread-1026543-1-4.html Leader/Follower 2635 / 100 = 26.35 (毫秒) Descriptor Passing 3644 / 100 = 36.44 (毫秒) spserver的测试结果: Leader/Follower 10 个线程:5220 / 100 = 52.2 (毫秒) HAHS 10 个线程: 10126 / 100 = 101.26 (毫秒) 测试结果比进程池差,因为在进行这个测试的过程中,使用 spserver 实现的时候,多了一些队列管理和内存的 copy 。 这些多出来的队列管理和内存 copy 主要的目前就是为了提高并发度。 如果不使用 spserver ,直接使用一个连接一个线程的线程池方式,估计和进程池应该差不多。 但是这种 Thread Per Connection 的方式,在并发度上就不如 spserver 了。 [ 本帖最后由 iunknown 于 2007-12-28 23:34 编辑 ] |
原文链接:http://bbs.chinaunix.net/viewthread.php?tid=957813 转载请注明作者名及原文出处 |










文章评论
共有 位网友发表了评论 查看完整内容