Skip to content

Latest commit

 

History

History
59 lines (30 loc) · 3.42 KB

谈谈Nginx快的原因.md

File metadata and controls

59 lines (30 loc) · 3.42 KB

谈谈Nginx快的原因

首先要明白,Nginx 采用的是多进程(单线程) & 多路IO复用模型。使用了 I/O 多路复用技术的 Nginx,就成了”并发事件驱动“的服务器。

多进程的工作模式 1、Nginx 在启动后,会有一个 master 进程和多个相互独立的 worker 进程。 2、master 接收来自外界的信号,向各 worker 进程发送信号,每个进程都有可能来处理这个连接。 3、master 进程能监控 worker 进程的运行状态,当 worker 进程退出后(异常情况下),会自动启动新的 worker 进程。

注意 worker 进程数,一般会设置成机器 cpu 核数。因为更多的 worker 数,只会导致进程相互竞争 cpu ,从而带来不必要的上下文切换。 使用多进程模式,不仅能提高并发率,而且进程之间相互独立,一个 worker 进程挂了不会影响到其他 worker 进程。

惊群现象 主进程(master 进程)首先通过 socket() 来创建一个 sock 文件描述符用来监听,然后fork生成子进程(workers 进程),子进程将继承父进程的 sockfd(socket 文件描述符),之后子进程 accept() 后将创建已连接描述符(connected descriptor),然后通过已连接描述符来与客户端通信。 那么,由于所有子进程都继承了父进程的 sockfd,那么当连接进来时,所有子进程都将收到通知并“争着”与它建立连接,这就叫“惊群现象”。大量的进程被激活又挂起,只有一个进程可以accept() 到这个连接,这当然会消耗系统资源。

Nginx对惊群现象的处理 Nginx 提供了一个 accept_mutex 这个东西,这是一个加在accept上的一把共享锁。即每个 worker 进程在执行 accept 之前都需要先获取锁,获取不到就放弃执行 accept()。有了这把锁之后,同一时刻,就只会有一个进程去 accpet(),这样就不会有惊群问题了。 accept_mutex 是一个可控选项,我们可以显示地关掉,默认是打开的。

Nginx进程详解 Nginx在启动后,会有一个master进程和多个worker进程。

master进程

主要用来管理worker进程,包含: 1、接收来自外界的信号 2、向各worker进程发送信号 3、监控worker进程的运行状态,当worker进程退出后(异常情况下),会自动重新启动新的worker进程

worker进程

而基本的网络事件,则是放在worker进程中来处理了。 多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。 一个请求只可能在一个worker进程中处理,一个worker进程不可能处理其它进程的请求。 worker进程的个数是可以设置的,一般我们会设置与机器cpu核数一致,这里面的原因与nginx的进程模型以及事件处理模型是分不开的。

核心:Nginx采用的 IO多路复用模型epoll 例子: Nginx 会注册一个事件:“如果来自一个新客户端的连接请求到来了,再通知我”,此后只有连接请求到来,服务器才会执行 accept() 来接收请求。 又比如向上游服务器(比如 PHP-FPM)转发请求,并等待请求返回时,这个处理的 worker 不会在这阻塞,它会在发送完请求后,注册一个事件:“如果缓冲区接收到数据了,告诉我一声,我再将它读进来”,于是进程就空闲下来等待事件发生。

参考 https://juejin.im/post/6847902216662024199