Nginx 多进程模型

Nginx 整体结构


Nginx运行在企业内网的边缘节点,也就是最外层,也就是边缘节点。它处理的流量是其他应用服务器处理流量的数倍,甚至是几个数量级。在应用场景下所有的问题都会被放大。所以有必要去了解master worker进程架构模型,如为什么要worker进程的数量要和CPU的核数相匹配。已经当我们要在多个worker进程之间共享数据的时候对TLS,以及限流限速的场景下内存的共享方式是有所不同的。这些都需要对nginx的架构有个清晰的了解

大致有WEB,EMAIL,TCP流量进入到nginx,nginx有三大状态机,一个是传输层状态机(处理TCP UDP的,四层传输层状态机)HTTP状态机(处理应用层)mail

在nginx使用反向代理的时候,对反向代理的内容可以做磁盘缓存,在处理静态资源的时候会有一个问题,当整个内存不足以缓存所有内容的时候,像sendfile这样的调用或者aio会退化成阻塞的磁盘调用。所以在这里有一个线程池来处理。

对于每个处理完的请求会记录access日志

 

 

Nginx 进程模型


众所周知,nginx性能高,而nginx的高性能与其架构是分不开的。那么nginx究竟是怎么样的呢?我们先来初识一下nginx框架吧。

nginx在启动后,在unix系统中会以daemon的方式在后台运行,后台进程包含一个master进程和多个worker进程。我们也可以手动地关掉后台模式,让nginx在前台运行,并且通过配置让nginx取消master进程,从而可以使nginx以单进程方式运行。很显然,生产环境下我们肯定不会这么做,所以关闭后台模式,一般是用来调试用的。所以,我们可以看到,nginx是以多进程的方式来工作的,当然nginx也是支持多线程的方式的,只是我们主流的方式还是多进程的方式,也是nginx的默认方式。nginx采用多进程的方式有诸多好处,所以我就主要讲解nginx的多进程模式吧。

Nginx 服务器,正常运行过程中:

  • 多进程:一个 Master 进程、多个 Worker 进程。

  • Master 进程:管理 Worker 进程。对外接口:接收外部的操作(信号);对内转发:根据外部的操作的不同,通过信号管理 Worker;监控:监控 Worker 进程的运行状态,Worker 进程异常终止后,自动重启 Worker 进程。

  • Worker 进程:所有 Worker 进程都是平等的。实际处理:网络请求,由 Worker 进程处理。Worker 进程数量:在 nginx.conf 中配置,一般设置为核心数,充分利用 CPU 资源,同时,避免进程数量过多,避免进程竞争 CPU 资源,增加上下文切换的损耗。

思考:

  • 请求是连接到 Nginx,Master 进程负责处理和转发?

  • 如何选定哪个 Worker 进程处理请求?请求的处理结果,是否还要经过 Master 进程?

 

 

Nginx最大连接数


基础背景:

  • Nginx 是多进程模型,Worker 进程用于处理请求。

  • 单个进程的连接数(文件描述符 fd),有上限(nofile):ulimit -n。

  • Nginx 上配置单个 Worker 进程的最大连接数:worker_connections 上限为 nofile。

  • Nginx 上配置 Worker 进程的数量:worker_processes。


因此,Nginx 的最大连接数:

  • Nginx 的最大连接数:Worker 进程数量 x 单个 Worker 进程的最大连接数。

  • 上面是 Nginx 作为通用服务器时,最大的连接数。

  • Nginx 作为反向代理服务器时,能够服务的最大连接数:(Worker 进程数量 x 单个 Worker 进程的最大连接数)/ 2。

  • Nginx 反向代理时,会建立 Client 的连接和后端 Web Server 的连接,占用 2 个连接。

 

HTTP连接建立和请求处理过程


HTTP 连接建立和请求处理过程如下:

  • Nginx 启动时,Master 进程,加载配置文件。

  • Master 进程,初始化监听的 Socket。

  • Master 进程,Fork 出多个 Worker 进程。

  • Worker 进程,竞争新的连接,获胜方通过三次握手,建立 Socket 连接,并处理请求。

 

补充说明


nginx在启动后,会有一个master进程和多个worker进程。master进程主要用来管理worker进程,包含:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程。而基本的网络事件,则是放在worker进程中来处理了。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。一个请求,只可能在一个worker进程中处理一个worker进程,不可能处理其它进程的请求。worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的。nginx的进程模型,可以由下图来表示:

master进程主要用来管理worker进程,具体包括如下4个主要功能:

(1)接收来自外界的信号。

(2)向各worker进程发送信号。

(3)监控woker进程的运行状态。

(4)当woker进程退出后(异常情况下),会自动重新启动新的woker进程。

woker进程主要用来处理网络事件,各个woker进程之间是对等且相互独立的,它们同等竞争来自客户端的请求,一个请求只可能在一个woker进程中处理,woker进程个数一般设置为机器CPU核数。

 

进程控制

在nginx启动后,如果我们要操作nginx,要怎么做呢?从上文中我们可以看到,master来管理worker进程,所以我们只需要与master进程通信就行了。master进程会接收来自外界发来的信号,再根据信号做不同的事情。所以我们要控制nginx,只需要通过kill向master进程发送信号就行了。比如kill -HUP pid,则是告诉nginx,从容地重启nginx,我们一般用这个信号来重启nginx,或重新加载配置,因为是从容地重启,因此服务是不中断的master进程在接收到HUP信号后是怎么做的呢?首先master进程在接到信号后,会先重新加载配置文件,然后再启动新的worker进程,并向所有老的worker进程发送信号,告诉他们可以光荣退休了。新的worker在启动后,就开始接收新的请求,而老的worker在收到来自master的信号后,就不再接收新的请求,并且在当前进程中的所有未处理完的请求处理完成后,再退出。当然,直接给master进程发送信号,这是比较老的操作方式,nginx在0.8版本之后,引入了一系列命令行参数,来方便我们管理。比如,./nginx -s reload,就是来重启nginx,./nginx -s stop,就是来停止nginx的运行。如何做到的呢?我们还是拿reload来说,我们看到,执行命令时,我们是启动一个新的nginx进程,而新的nginx进程在解析到reload参数后,就知道我们的目的是控制nginx来重新加载配置文件了,它会向master进程发送信号,然后接下来的动作,就和我们直接向master进程发送信号一样了。

现在,我们知道了当我们在操作nginx的时候,nginx内部做了些什么事情,那么,worker进程又是如何处理请求的呢?我们前面有提到,worker进程之间是平等的,每个进程,处理请求的机会也是一样的。当我们提供80端口的http服务时,一个连接请求过来,每个进程都有可能处理这个连接,怎么做到的呢?首先,每个worker进程都是从master进程fork过来,在master进程里面,先建立好需要listen的socket(listenfd)之后,然后再fork出多个worker进程。所有worker进程的listenfd会在新连接到来时变得可读,为保证只有一个进程处理该连接,所有worker进程在注册listenfd读事件前抢accept_mutex,抢到互斥锁的那个进程注册listenfd读事件,在读事件里调用accept接受该连接。当一个worker进程在accept这个连接之后,就开始读取请求,解析请求,处理请求,产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。我们可以看到,一个请求,完全由worker进程来处理,而且只在一个worker进程中处理。

那么,nginx采用这种进程模型有什么好处呢?当然,好处肯定会很多了。首先,对于每个worker进程来说,独立的进程,不需要加锁,所以省掉了锁带来的开销,同时在编程以及问题查找时,也会方便很多。其次,采用独立的进程,可以让互相之间不会影响,一个进程退出后,其它进程还在工作,服务不会中断,master进程则很快启动新的worker进程。当然,worker进程的异常退出,肯定是程序有bug了,异常退出,会导致当前worker上的所有请求失败,不过不会影响到所有请求,所以降低了风险。当然,好处还有很多,大家可以慢慢体会。

说明:

Nginx 要保证它的高可用 高可靠性, 如果Nginx 使用了多线程的时候,由于线程之间是共享同一个地址空间的,当某一个第三方模块引发了一个地址空间导致的断错时 (eg: 地址越界), 会导致整个Nginx全部挂掉; 当采用多进程来实现时, 往往不会出现这个问题.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值