10种大并发服务器设计方案

版权声明:guojawee https://blog.csdn.net/weixin_36750623/article/details/84329044

常见并发服务器方案

  1. 循环式/迭代式服务器:短链接
    缺点:无法充分利用多核CPU,不适合执行时间较长的服务

  2. 并发式服务器:长连接
    (1)主进程负责监听client的连接请求
    (2)当连接建立后,新fork一个子进程与client通信
    适应场景:适用于执行时间比较长的服务
    在这里插入图片描述

  3. prefork服务器
    (1)父进程进行listen,然后先fork出大量的子进程===>此时,父子进程都listen客户端的到来
    (2)当client连接到来时,可能导致大量的accept返回,但是只有一个accept返回是正确的(只有一个能建立连接成功),其他的是错误的,这种现象叫做“惊群现象”,关于惊群现象请参考UNP2e 第27章
    在这里插入图片描述

  4. 反应式(reactive)服务器(reactor模式)
    (1)select/poll/epoll
    (2)并发处理多个请求,实际上是在一个线程中完成。无法充分利用多核CPU
    (3)不适合执行时间比较长的服务,所以为了让客户感觉是在“并发”处理而不是“循环”处理,每个请求必须在相对较短时间内执行
    在这里插入图片描述

  5. reactor + thread per request (过渡方案)

  6. reactor + worker thread (过渡方案)

  7. reactor + thread pool (能适应密集计算)
    (1) Reactor监听到读事件到来后,将调用read函数读取数据,此过程参考select服务器程序,是在单线程中完成的
    (2) 将上面读到的数据,封装成一个一个的任务,添加到任务队列中,并通知线程池中的空闲线程去处理任务(decode、compute、encode)
    (3) 当处理完一条任务后,再将处理的结果添加到select的写事件上
    (4) select发现可写事件发生,就会调用send将数据发送出去
    总结:此模式是reactor + thread per request模式的升级版本,因为select仅仅只进行I/O操作,比较耗时的compute任务由线程去处理,所以该模式适用于计算密集型任务。
    在这里插入图片描述

  8. multiple reactors (能适应更大的突发I/O)
    reactor in threads ( one Eventloop per thread ) 每个线程都是一个事件循环
    reactor in processes ( one loop per process)
    特点:
    (1) 该模式有多个reactor,即有多个事件循环
    (2) 每个reactor都是一个线程或者一个进程
    优点:
    当只使用一个mainReactor进行监听listenfd、conn_fd的读事件时,可能mainReactor会出现瓶颈,而使用mainReactor+subReactor+subReactor的方式可以解决瓶颈的问题
    **如何使用?**假设有3个千兆网卡,可以每个网卡都分配一个subReactor
    模式执行流程详解:
    (1) mainReactor、subReactor、subReactor分别处在三个线程中
    (2) mainReactor中存放着listenfd,监听listenfd的读事件
    (3) 当发现client连接请求后,由acceptor接收连接,并把接收到的连接conn_fd1放入subReactor1中,由subReactor1监听conn_fd1的读事件
    (4) 当再次发现client连接请求后,由acceptor接收连接,并把接收到的连接conn_fd2放入subReactor2中,由subReactor2监听conn_fd2的读事件
    (5) 当再次发现client连接请求后,由acceptor接收连接,并把接收到的连接conn_fd3放入subReactor1中,由subReactor1监听conn_fd3的读事件
    (6) 下次连接放入subReactor2中,… …,新的连接交替的放入subReactor1、subReactor2,此种方式叫“伦叫”(round robin),可以保证连接均匀的分布到多个subReactor/事件循环中。
    在这里插入图片描述

  9. multiple reactors + thread pool (one loop per thread + threadpool) (突发I/O与密集计算)
    说明:该模式是在 multiple reactors 模式上添加了thread pool,用来解决耗时的compute操作
    在这里插入图片描述

  10. proactor服务器 (proactor模式,基于异步I/O)
    (1)理论上 proactor比reactor效率更高一些
    (2)异步I/O能够让I/O操作与计算重叠。充分利用DMA直接存储访问特性
    (3)Linux异步IO

[1] glibc aio (aio* ),有bug
[2] kernel native aio (aio*),也不完美。目前仅支持O_DIRECT方式来对磁盘读写,跳过系统缓存。要自己实现缓存,难度不小

(4)boost asio实现的proactor,实际上不是真正意义上的异步I/O,底层是用epoll来实现的,模拟异步I/O的

man aio_read

int aio_read(struct aiocb *aiocbp);

man 7 aio
struct aiocb {
   /* The order of these fields is implementation-dependent */
   int             aio_fildes;     /* File descriptor */
   off_t           aio_offset;     /* File offset */
   volatile void  *aio_buf;    缓冲区    /* Location of buffer */
   size_t          aio_nbytes;     /* Length of transfer */
   int             aio_reqprio;    /* Request priority */
   struct sigevent aio_sigevent;   /* Notification method */
   int             aio_lio_opcode; /* Operation to be performed;
                                      lio_listio() only */
   /* Various implementation-internal fields not shown */
};

猜你喜欢

转载自blog.csdn.net/weixin_36750623/article/details/84329044