首页线程间通信 › 网络服务端开发小结(短连接、长连接、进程池、线程池)

网络服务端开发小结(短连接、长连接、进程池、线程池)

平时对网络编程方面比较感兴趣,看了一些相关的资料,自己也尝试写过一些不同网络模型的服务程序。这次刚好有一个新的需求,需要开发一个转发服务器。之前开发的项目,网络通讯都是处理联机交易的,网络连接都是采用短连接,这次的服务端,采用长连接的方式。

1. 轮询和主动通知选择

公司有一个客户端产品(CLIENT),因为需要从多个客户的服务端获(SERVER)取信息,原有的设计是每个客户端通过SOCKET不断的轮询访问服务端获取信息。当CLIENT的数量不多时,轮询访问对服务端压力不大,但是当CLIENT的数量比较多时,这样的访问对服务器的压力就比较大,而且很低效。为了降低CLIENT对服务端的压力和提高信息的获取效率,采用让SERVER主动通知CLIENT的方式。不可能让每个客户SERVER都开发一个通知的服务端,所以需要一个和SERVER通讯并且把消息通知给CLIENT的转发服务端(简称TransmitServer).系统整体架构如下:

SERVER    ————–>       RECV   ——->  TransmitServer—————>CLIENT

SERVER把消息发给RECV, RECV通过消息队列发给TransmitServer,TransmitServer再把消息通知给相应的CLIENT。

2.短连接和长连接选择

因为是通知消息的方式,所以如果使用短连接的话,让TransmitServer去和ClENT主动建立连接是不可行的,那样就要让TransmitServer知道所有CLIENT的通讯地址,这是一种很笨的方式,所以不采用。当然如果使用短连接轮询的方式,让CLIENT去访问TransmitServer,TransmitServer访问SERVER,对SERVER的压力也能得到解决.

3.  进程管理方式和I/O复用的选择

网络连接处理的模型有很多,按照进程的管理方式,我分为2类,进程池和多进程(还包括线程),以及每种方式还可以选择是否应该使用I/O复用。

这里说的进程池和多进程是,进程池是预先启动多个子进程,并且可以管理进程;多进程是指到主进程阻塞于ACCEPT处理连接请求,由子进程 单独负责每个套接口连接。

处理短连接连接,因为客户端频繁的连接服务器和断开连接,服务端的主要性能开销应该是在进程切换上,基于性能考虑采用进程池的方式会比多进程好.如果连接并发量不大,没有性能上的问题,多进程的程序会比进程池简单很多。

如果服务端处理的是长连接。如果让进程池或者多进程中一个子进程只处理一个连接,系统的主要性能开销主要取决于进程的数量,在进程的数量到一定数量的时候,会对服务器造成比较大的压力。所以在处理长连接时,一般才用I/O多路复用的方式,LINUX上I/O多路复用,有SELECT、EPOLL等。

使用I/O多路复用一方面可以让单个进程同时多个连接,可以提高并发连接数。另一方面,还可以可以让CLIENT和SERVER的通讯更加灵活,例如使用I/O多路复用,让CLIENT和SERVER可以很容易的异步通讯。

4. 线程和进程的选择

使用I/O多路复用,让单个进程可以处理多个连接,如果进程池只有一个进程, 同一个服务进程里的连接之间可以很方便的通讯,但是如果是多个子进程,那么子进程之间就不能直接通讯,通常要要消息队列、共享内存、管道等。当服务端需要处理连接之间的交互,而且性能上需要多个进程,那么使用线程池代替进程池应该是一种比较好的方式。线程和进程相比较,线程的优点是性能开销更小,因为在同一个进程空间里,线程之间的通讯很容易;因为线程共享进程空间数据,因此线程在处理的时候比进程更容易出错,线程池的方式简化了通讯方式,但是为了线程安全,这方面的复杂性就增加了。所以如果网络连接之间并不需要很多交互,每个连接处理都是独立的,那么应该选择进程。这个原则不但对网络处理,对于别的处理也是如此。

综合上面几点服务端网络模型的选择,主要是根据业务选择使用长连接或者短连接,根据连接方式。长连接一般使用线程池+I/O复用,例如网络游戏、聊天室等。短连接一般是进程池或者多进程,因为短连接不需要连接之间的交互,每个连接都是独立的,所以使用进程更加合适。

参考书目:

W.Richard Stevens <<UNIX网络编程(第一卷)>>

W.Richard Stevens <<UNIX高级环境编程>>

DEMO示例:

发表评论