Nginx 高速并发处理模型

一 概述  

本文系原创,同时发布于 F5 Network社区

Nginx是一款高性能webserver软件。除此以外它还具有很强的负载均衡,反向代理,邮件代理以及静态缓存的功能。在提供这些功能的同时,Nginx通过优秀的架构设计,实现了高速的高并发处理。

这篇文章我们通过分析Nginx的框架结构,来解释它的高速并发处理的背后原因。

二 框架结构

如下图所示,Nginx结合采用多进程和IO多路复用的结构处理并发客户请求。

Master进程主要负责信号处理,监控和管理Worker进程。 Master进程本身不处理具体业务。Worker进程处理具体业务,包括处理连接请求和网络读写事件的处理。多个worker进程可以独立地处理各自的客户连接。Worker进程之间通过信号量和共享内存进行通信。

Caption

 

                                                                         图1  Nginx整体架构

通过配置与系统CPU等量的worker进程,可以实现某一个进程绑定某一个特定CPU从而减少系统开销。

在每一个worker进程处理多个client并发连接请求时,Nginx 采用IO多路复用技术在一个进程内同时处理多个client的网络读写事件。与多进程/线程处理多连接请求模型相比,IO多路复用可以减少大量的进程调度带来的系统开销,从而提高系统整体的处理性能。

下面我们来进一步研究Nginx采用的多进程和IO多路复用机制。

三 并发连接请求处理方法

1 并发处理方式

Caption

                                                                      图2  网络socket编程流程

网络服务器在处理并发处理方式,如上图socket处理流程所示,根据accept得到新连接以后是启用新的进程/线程还是直接在原来本进程内处理,分为如下两种方式。

一种是多进程/线程方式,这种方式为每一个新来的连接生成一个新的进程/线程来单独处理。

另外一种是IO多路复用,这种方式在一个进程/线程中维护所有的连接的socket,通过事件处理的方式依次处理所有连接上的网络事件。

多线程模型如下:

Caption

                                                                             图3 多进程/线程模型

IO多路复用模型如下:

Caption

                                                                  图4  IO多路复用模型

2 多进程/线程模型

2.1 模型种类

在多进程/线程的模型中,根据accept在新老进程中的位置又分为两种。一种类型是accept在父进程中进行,每次accept以后,fork一个新进程或者创建一个新线程来处理新accept的连接。一种类型是父进程在listen调用以后,fork出多个进程或者创建多个线程分别进行accept.

Caption

                                                                             图5  accept后创建进程/线程

Caption

                                                                           图6 新进程/线程里执行accept

除此以外,随着Linux3.9版本对SO_REUSEPORT模式的支持,可以允许多个进程同时绑定在同一个地址的相同的port上。所以,下面的模型也开始被Nginx支持。

Caption

                                                                              图7  SO_REUSEPORT模型

2.2三种进程/线程模型比较

第一种模型accept以后再fork一个新的进程/线程处理连接,在大流量并发的情况下,主进程需要处理所有的连接请求,在大量并发新连接环境下,accept主进程会成为瓶颈。

第二种模型,解决了第一种模型中的accept瓶颈问题。每一个进程/线程都可以处理连接请求。但是又引入了“网络惊群”的问题。这个问题就是,当有一个新的连接到来时,所有准备accept的进程/线程都会被唤起去抢夺这个新的连接。为了解决这个问题,Nginx在Linux2.6以前的版本引入了一个accept mutex文件锁,各个worker进程竞争这个accetp mutex。新的连接会被持有accept mutex的进程处理。Linux2.6内核已经有效解决了“网络惊群”的问题。可以通过配置来选择是否需要accept mutex机制。

第三种模型是建立Linux 3.9内核支持SO_REUSEPORT选项的基础上。这种模型本身不再有“网络惊群”问题。通过这个选项,可以允许多个进程同时监听同一个地址和端口。当有新的连接到来时,内核会选择某一个进程进行唤起,从而在内核级别把新连接请求相对公平地分配到不同的worker进程中。

多进程/线程的处理模型,在高并发的情况下,需要大量的进程/线程来处理连接,系统负担会比较大。在多线程模型中,因为多个线程共享系统资源,一个线程出问题整个系统都会出现问题,因此,稳定性比较差。

Nginx可以通过配置文件(有的选项需要内核支持),采用第二种或者第三种模型。在第二种模型中,也可以通过配置选择是否使用accept mutex解决网络惊群问题。

3 IO多路复用模型

IO多路复用,又称为event driven IO就是在同一个进程内同时处理多路IO,进而提高系统吞吐量。一般是通过维护一个连接池,当某个连接有数据到达,通知进程来进行数据处理。

3.1 多路复用的方式

Nginx支持多种并发连接请求,比如select,poll,epoll,kqueue(针对bsd)等等,这些请求可以通过配置文件进行选择。一般在linux上epoll的效率要比select,poll高很多。

3.2 select/poll原理

Select和Poll方式大体原理一样,区别在于Poll支持同时处理的socket数量更多。Select一般最多支持同时处理1024个连接。

Caption

 

                                                               图8  Select 实现数据结构

Select和Poll需要经历维护等待队列和堵塞进程两个阶段。在支持大量socket处理的场景下,效率比较低。主要原因在于select的执行过程有如下三次遍历链表操作。

  1. 进程调用select/poll 时,会被加入到所有需要处理的socket的等待队列里。
  2. 任何一个socket有数据到来,就会把进程唤起。同时遍历所有的socket,把进程从这些socket等待队列中移除。
  3. 进程被唤起运行以后,需要再次遍历所有监听的socket,依次去判断哪些socket有数据要处理。

处理完毕以后,再次调用select时,需要重复步骤1.

这种实现方式,在处理大量连接时,socket链表会比较长,处理过程中的三次循环会非常消耗时间。

3.3 epoll原理

Caption

 

                                                             图9  epoll实现数据结构

如上图所示,epoll相对于select,在socket和用户进程之间加入了一个eventPoll和rdlist结构。

eventPll本身是一个文件句柄,通过Add/Del等操作把socket按照红黑树的数据结构加入或者移除到eventPoll中。

rdlist是一个就绪队列,当某一socket有数据到达时,内核一方面唤醒用户进程,另一方面把自身加入到rdlist中。

这样,用户进程在得到运行时,在rdlist中就可以得到所有的有数据的socket,而不需要像select那样遍历所有的socket列表来查找有数据需要处理的socket。epoll的操作有效的避免了select操作的三次循环操作,因此很好地提高了并发运行的效率。

四 总结

综上所述, Nginx通过本身优秀的框架设计,加上内核对并行网络处理的支持,得到了非常好的并发处理性能。

下列两幅图分别表示在系统层面,一个单队列的网卡和多队列网卡在Linux系统中,是如何最大限度地保证客户并发处理的并行处理。

通过把某些client的请求被特定的CPU上面的特定Nginx worker进程处理的,最大限度地减少了资源共享和CPU进程切换从而保证了CPU Cache的热度,进而提高了整体系统的并发处理能力。

                                                                       图10  单队列网卡处理结构

Caption

                                                                          图11  多队列网卡处理结构

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要计算nginx并发处理量,需要考虑多个因素,包括硬件配置、网络带宽和nginx的配置参数。其中,nginx的配置参数可以通过修改nginx.conf文件来调整。 在nginx.conf文件中,可以通过配置worker_processes参数来指定worker进程的数量。每个worker进程都可以处理多个并发请求。同时,还可以通过修改worker_connections参数来限制每个worker进程的最大并发连接数。 除了这些配置参数,还可以通过其他配置和优化操作提高nginx并发处理能力,例如启用缓存、压缩和负载均衡等。 根据引用中的配置信息,可以看到安装并配置nginx的过程,但是没有提供具体的worker_processes和worker_connections参数的设置。因此,无法直接确定nginx并发处理量。 为了更准确地计算nginx并发处理量,需要结合实际的硬件配置和网络环境。可以通过性能测试工具,如ab、wrk等,来模拟并发请求并测量nginx处理能力。在测试过程中,可以逐步调整worker_processes和worker_connections参数,并监控系统资源使用情况,以找到最佳的配置值。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [源码编译Nginx服务器及其配置与应用](https://blog.csdn.net/qq_35456705/article/details/113207253)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值