Nginx技术总结之二——Nginx进程模型

时间:2022-07-22
本文章向大家介绍Nginx技术总结之二——Nginx进程模型,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

接上篇:Nginx技术总结之一——Nginx模块与工作原理

二. Nginx 的进程模型

Nginx 的进程模型,可以由下图来表示:

在工作方式上,Nginx 分为单工作进程多工作进程两种模式。

  • 单工作进程模式:除主进程外,还有一个工作进程,工作进程是单线程的;
  • 多工作进程模式:每个工作进程包含多个线程。Nginx 默认为单工作进程模式;

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

2.1 master 进程

master 进程主要用来管理 worker 进程,包含:接收来自外界的信号,向各 worker 进程发送信号,监控 worker 进程的运行状态,当异常情况下 worker 进程退出后,会自动重新启动新的 worker 进程。 master 进程充当整个进程组与用户的交互接口,同时对进程进行监护。它不需要处理网络事件,不负责业务的执行,只会通过管理 worker 进程来实现重启服务、平滑升级、更换日志文件、配置文件实时生效等功能。 我们要控制 Nginx,只需要通过 kill 向 master 进程发送信号就行了。比如 kill -HUP pid,我们一般用这个信号来重启 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 进程发送信号一样了。

2.2 Worker

基本的网络事件,则是放在 worker 进程中来处理了。多个 worker 进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的,一个请求只可能在一个 worker 进程中处理。worker 进程的个数是可以设置的,一般我们会设置与机器 CPU 核数一致,这里面的原因与 Nginx 的进程模型以及事件处理模型是分不开的。 worker 进程之间是平等的,每个进程,处理请求的机会也是一样的。当我们提供 80 端口的 HTTP 服务时,一个连接请求过来,每个进程都有可能处理这个连接,怎么做到的呢?步骤如下:

  1. 每个 worker 进程都是从 master 进程 fork 过来,在 master 进程里面,建立好需要 listen 的 socket (listenfd) 之后;
  2. fork 出多个 worker 进程;
  3. 所有 worker 进程的 listenfd 会在新连接到来时变得可读,为保证只有一个进程处理该连接,所有 worker 进程在注册 listenfd 读事件前抢 accept_mutex,抢到互斥锁的 worker 进程注册 listenfd 读事件;在读事件里调用 accept 接受该连接。
  4. 当一个 worker 进程在 accept 这个连接之后,就开始读取请求,解析请求,处理请求。产生数据后,再返回给客户端,最后才断开连接;

一个完整的请求就是这样的了。

我们可以看到,一个请求,完全由 worker 进程来处理,且只在一个 worker 进程中处理。