Nginx 学习笔记--进程与模块
进程与模块(一)
简介
Nginx 的代码是由一个 核心 和一系列的 模块 组成。
Nginx 由内核和一系列模块组成:内核提供web服务的基本功能,如启用网络协议、创建运行环境、接收和分配客户端请求、处理模块之间的交互。模块实现Nginx的各种功能和操作,Nginx的模块从结构上分为核心模块、基础模块和第三方模块。
- 核心模块:HTTP模块、EVENT模块和MAIL模块
- 基础模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块
- 第三方模块:HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块及用户自己开发的模块
这样的设计使 Nginx 方便开发和扩展,也正因此才使得 Nginx 功能如此强大。Nginx 的模块默认编译进 Nginx 中,如果需要增加或删除模块,需要重新编译 Nginx,这一点不如 Apache 的动态加载模块方便。如果有需要动态加载模块,可以使用由淘宝网发起的 Web 服务器 Tengine,在 Nginx 的基础上增加了很多高级特性,完全兼容 Nginx,已被国内很多网站采用。
进程
首先我们要知道 Nginx 是以多进程的方式进行工作的。Nginx在Linux系统启动后,会以守护进程(daemon)的方式在后台运行,后台进程包括一个 master
进程和多个 worker
进程。
master
进程
master进程主要用来管理worker进程,master的工作:接收来自外界的信号,向各worker进程发送信号,监控worker进程的运行状态,当worker进程退出后(异常关闭下),重新开启新的worker进程。
master 进程主要完成如下工作:
读取并验证配置信息
创建、绑定及关闭套接字
启动、终止worker进程及维护worker进程的个数
无须终止服务而重新配置工作
控制非中断式程序升级、启用新的二进制程序及在有需要时回滚至老版本
重新打开日志文件
编译嵌入式Perl脚本
worker
进程
对于基本的网络请求,Nginx则是放在worker进程来处理。多个worker进程之间是对等的,他们同等竞争来自客户端的请求,各进程之间相互独立。
一个请求,只能在一个worker进程中处理, 一个worker进程,不可能处理其它进程的请求。之间的关系是一对一。
Nginx在启动时,创建一组初始的监听套接字,HTTP 请求和响应之时,worker 连续接收、读取和写入套接字。
worker 进程主要完成如下工作:
- 接收、传入并处理来自客户端的请求
- 提供反向代理及过滤功能
- nginx任何能完成的其他任务
既然 worker 进程之间是平等的,每个进程,处理请求的机会也是一样的。当我们提供 80
端口的 http
服务时,一个连接请求过来,每个进程都有可能处理这个连接。那么问题来了,到底最后怎样处理,是由什么决定的呢?我们来看一看一个完整的请求是怎样通过互相的协作来实现的:
- 首先,每个 worker 进程都是从 master 进程
fork
过来,在 master 进程里面,先建立好需要listen
的socket
(listenfd
)之后,然后再fork
出多个 worker 进程。 - 所有 worker 进程的
listenfd
会在新连接到来时变得可读,为保证只有一个进程处理该连接,所有 worker 进程会在注册listenfd
读事件前抢accept_mutex
,抢到互斥锁的那个进程注册listenfd
读事件,然后在读事件里调用accept
接受该连接。 - 当一个 worker 进程在
accept
这个连接之后,就开始读取请求、解析请求、处理请求。产生数据后,再返回给客户端,最后才断开连接,这样一个完整的请求就是这样的了。
我们可以看到:一个请求,完全由 worker 进程来处理,而且只在一个 worker 进程中处理。
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: