本章涉及内容:
- 模块化结构的相关知识
- Nginx 如何处理Web请求
- Nginx的事件驱动模型
- Nginx的事件驱动模型。
- Nginx设计架构的概述。
3.1、模块化结构
3.1.1、什么是“模块化设计”
定义:以功能块为单元进行程序设计,实现其求解算法的方法
包含意思:
一个模块一个功能,“单一职责原则”
程序分解,自顶向下,逐步求精原则
各个模块之间依赖不能太强, 高内聚、低耦合原则。
3.1.2、Nginx模块化结构
分为核心模块、标准HTTP模块、可选HTTP模块、邮件服务模块以及第三方模块等五大类
可以在下载解压文件中,objs/文件夹下有个ngx_modules.c罗列编译后所有固有模块的声明
extern关键字修饰,因此各模块均可以被其他模块访问,类似public
所有固有模块的源码放在编译目录下src目录中。
快速编译不会讲mail编译到nginx中
1、核心模块
一类主体功能,包括进程管理、权限控制,错误日志记录、配置解析,另一类是用于响应请求事件必须的功能,包括事件驱动机制、正则表达式解析等
2、标准HTTP模块
基本HTTP服务、高级HTTP服务和邮件服务等,默认会编译到nginx中,如果不想要,可以--without-XXX参数声明不编译
3、可选HTTP模块
可选HTTP模块只提供源码,必须在配置时使用--with-XXX参数声明才会编译的。
4、邮件服务模块
包括对POP3协议,IMAP协议和SMTP协议支持
5、第三方模块
自定义模块,各位大神开发模块。
3.2、Nginx服务器的Web请求处理机制
完成并行处理请求工作方式有个三种方式可选:多进程方式、多线程方式和异步方式
3.2.1、多进程方式
每一次客户端来连,自动生成一个子进程、
优点:设计和实现简单,各个进程之间不会干扰,保证服务稳定
缺点:系统资源压力,导致系统性能下降 (Apache最初也是这个架构)
3.2.2、多线程方式
每一次客户端来连,自动分配一个线程为它服务
优点:资源消耗小,线程任务调度比较方便
缺点:各个线程之间可能相互影响,线程管理方面不足,特别内存读取方面。长期运行会产生错误积累
3.2.3、异步方式
简单理解,通知某个人做某事,不要监督他,你可以做其他事情。
同步阻塞、异步阻塞、同步非阻塞、异步非阻塞。
打个比喻解释:领导 和 员工
同步阻塞:领导一直监督员工完成他安排的任务才肯罢休,中途可以员工不能做其它任何事情。
异步阻塞:领导通知员工完成某个任务,然后他自己忙自己活去了,这个时候,员工必须将先将这个事件弄完,否则不让他做其它事件。
同步非阻塞:领导一直监督员工完成他安排的任务,但是员工可能会接收其它任务,这时候他可以做其它这些任务,但是领导一直在你回复呢,看你什么时候回复他
异步非阻塞:领导通知员工完成某个任务,然后他自己忙自己活去了,这个时候,员工可以不用立即做这个事情。只要有结果再返回领导
所有最后一种是效率最高的。
3.2.4、Nginx服务器如何处理请求
Nginx服务器的一个显著优势是能够同时处理大量并发请求。它结合多进程机制和异步机制对外提供服务
Nginx服务器的进程有两种:Single模型和Master-Worker模型。Single模型为单进程方式,性能差,Master-Worker 就是Master-Slave,在服务器中充当Slave角色的是工作进程
3.2.5、Nginx服务器的事件处理机制
Nginx服务工作进程调用IO后,就去进行其他工作了;当IO调用返回后,会通知工作进程,这里有问题,IO调用是如何将自己的状态通知给工作进程的呢?
一种:让工作进程在进行其他工作的过程中间隔一段时间就去检查一下IO的运行状态,如果完成,就去响应客户端,如果没有完成,继续正在进行的工作
二种:IO调用在完成后能主动通知工作进程
简单来说:第一种是领导询问员工工作,第二种员工主动上报工作。肯定是第二种效率更高
select/poll/epoll/kqueue 这样的系统调用就是用来支持第二种解决方案的,这些系统调用,也常称为事件驱动模型。
3.3、Nginx服务器的事件驱动模型
3.3.1、事件驱动模型概述
事件驱动模型一般是由事件收集器、事件发送器和事件处理器三个部分基本单元组成
3.3.2、Nginx中的事件驱动模型
实现事件驱动模型有三种方式
“事件发送器”每传递过来一个请求, “目标对象”就创建一个新的进程,调用“事件处理器”来处理该请求 (开销大,编程简单)
“事情发送器”每传递过来一个请求,“目标对象”就创建一个新的线程,调用“事件处理器”来处理器该请求 (涉及线程同步,死锁、同步问题)
“事件发送器”每传递过来一个请求,“目标对象”就将其放入一个待处理事件的列表,使用非阻塞IO方式调用“事件处理器”来处理该请求。(编程复杂,效率高)
第三种形成了所谓的“事件驱动处理库” 它又称为多路IO复用方法,最常见包含以下三种:select模型、poll模型和epoll模型
Nginx服务器还支持rtsig模型、kqueue模型、dev/poll模型和eventport模型
3.3.3 select库
首先创建关注事件的描述符集合。对于一个描述符,可以关注其上面的读(Read)事件、写(Write)事件以及异常发生(Exception)事件,所以要创建三类事件描述符集合,分别用来收集读事件的描述符、写事件的描述符合异常事件的描述符。
没有指定自动编译该库可以使用--with-select_module 和 --without-select_module两个参数强制Nginx是否编译该库、
需要主动轮询事件列表
3.3.4、poll库
Windows平台不支持poll
它和select库类似,唯一区别,它只需要创建一个集合,而select需要创建三个集合
3.3.5、epoll库
这个与前面不同的是,它把需要监听事件列表写入内核中去,内核通知epoll进行处理,这个是linux平台效率最高的
3.3.6、rtsig模型
rtsig 是Real-Time Signal 的缩写,是实时信号的意思, 它队列有长度限制,超过这个长度后会溢出,这是会poll库进行处理
3.3.7、其他事件驱动模型
kqueue模型:它用于支持BSD系列平台的高效事件驱动模型,类似触发操作
/dev/poll模型:是用于支持Unix衍生平台的高效事件驱动模型。
eventport模型:用于支持Solaris10以及版本平台的高效事件驱动模型
3.4、设计架构概览
3.4.1、Nginx服务器架构
这个图摘自《Nginx高性能Web服务器详解》
3.4.2、Nginx服务器的进程
1、主线程(Master Process):主要功能是与外界通信和对内部其他进程进行管理
2、工作进程(Worker Process):由主进程生成,生成数量可以通过Nginx配置文件指定,正常情况下生存于主进程的整个生命周期
3、缓存索引重建及管理进程(Cache Loader & Cache Manager)
3.4.3、进程交互
1、Master-Worker交互
主进程生成工作进程之后,会在工作进程表中添加,并建立一个单向管道并将其传递给该工作进程。(它不同于普通管道,它是单向)
主进程与外界通过信号机制进行通信,当接收到需要处理的信号时,它通过管道向相关的工作进程发送正确读的指令
2、Worker-Worker交互
工作进程之间通讯,需要通过Master进程查看一下工作进程列表找到对应进程ID,然后写给请求者。
3.4.4、Run Loops 事件处理循环模型
Run Loops 指的是进程内部用来不停地调配工作,对事件进行循环处理的模型