Skip to content

并发服务器模型

循环式迭代式模型

一种单线程的应用程序,它只能使用短连接而不能使用长连接,缺点是无法充分利用多核CPU,不适合执行时间较长的服务,即适用于短连接(这样可以处理多个客户端),如果是长连接则需要在read/write之间循环,那么只能服务一个客户端。所以循环式服务器只能使用短连接,而不能使用长链接,否则无法处理多个客户端的请求,因为整个程序是一个单线程的应用程序。

并发式服务器

适合执行时间比较长的服务。在父进程中要关闭创建连接的套接字,等待下一个客户端请求连接,所以可以并发式服务器处理多个客户端的请求,一个客户端一个进程;子进程在处理客户端的请求,子进程是长连接的,不断的处理请求,即使子进程中解包,计算,打包的过程时间过长,也不会影响父进程去连接其他客户端的请求。本模型也适用于线程,主线程每次accept 回来就创建一个子线程服务,由于线程共享文件描述符,故不用关闭,最后一个线程关闭监听套接字。

prefork服务器

它处理连接的进程/线程都是预先创建好的,因此可以减小创建进程/线程的开销,能够提高响应速速。进程预先fork了n个子进程(n的数目需要提前设定),每个子进程负责和客户端的通信,每个子进程执行的都是右图的流程。前面的创建套接字,绑定端口号,监听套接字这些步骤,每个预先创建的进程已经完成,他们分别调用accept并由内核置入睡眠状态。这种服务器的优点是:提高了响应速度,不需要引入父进程执行fork的开销,新客户就能得到处理。缺点在于:每次启动服务器,父进程必须预测到底需要产生多少子进程,还有一个就是如果不考虑再派生子进程,先前派生的子进程可能被客户请求占用完,以后新到的请求只能先完成三次握手,并且达到listen接口的最大并发连接数backlog,直到有子进程可用。服务器才调用accept,将这些已经完成的连接传递给accept。

反应式服务器

服务器可以并发处理多个请求。不过本质上这些请求还是在一个线程中完成的,即:单线程轮询多个客户端。也无法充分利用多核CPU,不适合执行时间比较长的服务,所以为了让客户感觉是在“并发”处理而不是“循环”处理,每个请求必须在相对较短时间内执行。当然如果这个请求不能在有限的时间内完成

我们可以将这个请求拆分开来,使用有限状态机机制来完成。其中的Reactor可以使用IO多路复用select/poll/epoll。

模型的过程解析:

  • Reactor是一个线程对象,该线程会启动事件循环,并使用select/poll/epoll来实现IO多路复用。注册一个Acceptor事件处理器到Reactor中,Acceptor事件处理器所关注的事件是accept事件,这样Reactor会监听客户端向服务器端发起的连接请求事件。
  • 客户端向服务器端发起一个连接请求,Reactor监听到了该accept事件的发生并将该accept事件派发给相应的Acceptor处理器来进行处理。Acceptor处理器通过accept方法得到与这个客户端对应的连接,然后将该连接所关注的读事件以及对应的read读事件处理器注册到Reactor中,这样Reactor就会监听该连接的read事件了。或者当你需要向客户端发送数据时,就向Reactor注册该连接的写事件和其处理器。
  • 当Reactor监听到有读或者写事件发生时,将调用dispatch将相关的事件分发给对应的处理器进行处理。比如,读处理器会通过read方法读取数据,此时read操作可以直接读取到数据,而不会堵塞与等待可读的数据到来。
  • 每当处理完所有就绪的I/O事件后,Reactor线程会再次执行IO多路复用的函数阻塞等待新的事件就绪并将其分派给对应处理器进行处理。

目前的单线程Reactor模式中,不仅I/O操作在该Reactor线程上,连非I/O的业务操作也在该线程上进行处理了,这可能会大大延迟I/O请求的响应。所以我们应该将非I/O的业务逻辑操作从Reactor线程上分离出去,以此来加速Reactor线程对I/O请求的响应。这种的服务器的并发量比并发式服务器多,因为并发式服务器能够创建的进程或者线程数目是有限的

反应式 + 线程池型服务器

与单线程Reactor模式不同的是,增加了线程池对象,并将业务逻辑的处理从Reactor线程中移出转交给工作的线程池来执行。这样能够提高Reactor线程的I/O响应,不至于因为一些耗时的业务逻辑而延迟对后面I/O请求的处理。

使用线程池带来的好处有如下几点:

  • 线程池中的线程是提前创建好的,这样可以在处理多个请求时分摊在线程创建和销毁过程产生的巨大开销。
  • 将IO操作与非IO操作分离,当请求到达时工作线程通常已经存在,因此不会由于等待创建线程而延迟任务的执行,从而提高了响应性。
  • 可以进行职责分离,让IO线程做IO操作,线程池处理业务逻辑,处理大量计算,充分利用CPU的计算优势。

多反应式服务器

一个主线程,多个工作线程,主线程Reactor负责接收客户端连接,每个线程有各自的Reactor负责执行任务队列中的任务。

多反应式+ 线程池模型

多个Reactor的模式,mainReactor与subReactor都是一个线程,因为多进程之间无法共享计算线程池。这种模型能够适用IO频繁且计算密集的服务。