点赞
评论
收藏
分享
举报
NGINX高速并发处理模型
发表于2020-09-18 08:52

浏览 973

概述

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

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

框架结构

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

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

NGINX整体架构

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

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

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

并发连接请求处理方法

1 并发处理方式

2 网络socket编程流程

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

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

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

多线程模型如下:

3 多进程/线程模型

IO多路复用模型如下:

4IO多路复用模型

2 多进程/线程模型

2.1 模型种类

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

5accept后创建进程/线程

6 新进程/线程里执行accept

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

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)等等,这些请求可以通过配置文件进行选择。一般在linuxepoll的效率要比select,poll高很多。

3.2 select/poll原理

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

8 Select 实现数据结构

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

1.     进程调用select/poll 时,会被加入到所有需要处理的socket的等待队列里。

2.     任何一个socket有数据到来,就会把进程唤起。同时遍历所有的socket,把进程从这些socket等待队列中移除。

3.     进程被唤起运行以后,需要再次遍历所有监听的socket,依次去判断哪些socket有数据要处理。

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

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

3.3 epoll原理

9 epoll实现数据结构

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

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

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

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

总结

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

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

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

10 单队列网卡处理结构

11 多队列网卡处理结构


已修改于2023-03-07 02:20
本作品系原创
创作不易,留下一份鼓励
皮皮鲁

暂无个人介绍

关注



写下您的评论
发表评论
全部评论(0)

按点赞数排序

按时间排序

关于作者
皮皮鲁
这家伙很懒还未留下介绍~
85
文章
2
问答
42
粉丝
相关文章
1、语法规则:location[=|~|~*|^~]/uri/{…}2、匹配规则:= 开头表示精确匹配 ^~ 开头表示uri以某个常规字符串开头,理解为匹配url路径即可。nginx不对url做编码,因此请求为/static/20%/aa,可以被规则^~/static//aa匹配到(注意是空格)。 ~ 开头表示区分大小写的正则匹配 ~* 开头表示不区分大小写的正则匹配 !~和!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则 / 通用匹配,任何请求都会匹配到。3、location搜索顺序 (location=)>(location完整路径)>(location^~路径)>(location~,~*正则顺序)>(location部分起始路径)>(/)4、匹配示例:location=/{#精确匹配/,主机名后面不能带任何字符串[configurationA]}location/{#因为所有
点赞 2
浏览 1.1k
使用MemcacheMemcache是一个通用的内存缓存系统。它通常用于加速缓慢的数据访问。 NGINXmemcached模块提供各种指令,可以配置为直接访问Memcache提供内容,从而避免对上游服务器的请求。除了指令之外,模块还创建𝑚𝑒𝑚𝑐𝑎𝑐ℎ𝑒𝑑𝑘𝑒𝑦变量,用于执行高速缓存查找。在使用𝑀𝑒𝑚𝑐𝑎𝑐ℎ𝑒查找之前,必须在memcachedkey变量,用于执行高速缓存查找。在使用Memcache查找之前,必须在memcached_key变量中设置一个值,该变量根据请求URL确定。memcached_pass此指令用于指定memcached服务器的位置。地址可以通过以下任意方式指定:•域名或IP地址,以及可选端口•使用带unix:前缀的的Unix域套接字•使用NGINX upstream指令创建的一组服务器该指令仅在NGINX配置的location和locationif中使用。如下例子:location/myloc/{  set 𝑚𝑒𝑚𝑎𝑐ℎ𝑒𝑑𝑘𝑒𝑦memachedkeyuri;  memcached
点赞 0
浏览 939
继 基于macvlan实现多租场景下的nginx集群部署实践(一)-NGINX开源社区 续步骤1:开启混杂模式2  在node1节点创建管理网子网卡ens33.0,并配置管理网地址
点赞 1
浏览 1.4k