阅读 66

Nginx高性能Web服务器之Nginx架构

Nginx服务器架构初探

模块化设计:没有统一的定义,各模块之间低耦合。

  • “功能块”是对模块的描述,一个模块就是一个功能块,应该只负责一个功能,在设计模式理论中类似于“单一职责原则”
  • “模块化”,即对程序进行分解——自顶向下,逐步求精原则
  • “高内聚,低耦合”,一个程序被分解为多个模块,模块之间一定要存在一定的依赖关系,但这个依赖不能太强。

Nginx服务器的Web请求处理机制

一般来说,完成并行处理请求工作方式有:多进程方式、多线程方式和异步方式。

多进程方式
多进程方式指的是,服务器每收到一个客户端时,就由服务器主进程生成一个子进程出来和该客户端建立连接进行交互,直到连接断开,该子进程就结束了。
多进程方式各子进程之间相互独立,处理客户端请求过程中彼此不受到干扰,确保了稳定性,但是进程本身占用太多的系统资源。

多线程方式
多线程方式指的是,服务器每收到一个客户端时,服务器主进程会生成一个线程和该客户端进行交互。
多线程能够很好地节省系统资源,但是多个线程位于同一个进程内,可以访问同样的内存空间,彼此之间相互影响。

异步方式
在异步机制中,所有来自发送方的请求形成一个队列,请求方处理完成后主动通知发送方。

同步阻塞BIO: 连接线程 (缓存、自己处理)
同步非阻塞NIO:请求线程(立即、自己处理)
异步非阻塞AIO:有效请求线程(立即、委托OS)

同步 vs 异步
JAVA自己处理IO读写 将IO读写委托给OS(系统)
服务器不会”主动“ 数据准备后,服务器会”主动“

阻塞 (不立即返回) vs 非阻塞(立即返回)
必须要等待数据返回 不需要等待数据返回
相对而言响应速度慢 响应速度快

Nginx处理请求的方式是多进程方式结合异步方法的方式:
Nginx服务器每收到一个客户端时,服务器主进程会生成一个子线程和该客户端进行交互,并且每一个子进程都采用异步非阻塞AIO的方式来处理请求。这样使得:
1.采用多进程的方式确保了服务器的稳定性,并且使得请求数的增长不会占用大量系统资源。
2.使用异步非阻塞的方式减少了工作进程在I/O调用上的阻塞延迟,保证了其对请求的处理能力。

Nginx服务器的事件处理机制

异步非阻塞AIO使得Nginx服务器的工作进程调用IO后,就去进行其他工作了;当IO调用返回时(即完成任务,做出响应),就会主动通知工作进程。
这种主动的方式称为事件驱动模型,它使得进程可以同时处理多个并发请求,不用关心IO调用的具体状态。IO调用完全由事件驱动模型来管理,事件准备好之后就通知工作进程事件已经就绪。

事件驱动模型一般是由事件收集器、事件发送器和事件处理器三个基本单元组成。

在Nginx服务器中,“事件发送器”每传递过来一个请求,“目标对象”就将其放入一个待处理事件的列表,使用非阻塞I/O方式调用“事件处理器”来处理该请求。
这种采用异步非阻塞的方式又叫做多路IO复用。
它的基本原理就是select,poll,epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程
在这里插入图片描述
select库
select库的使用步骤
1.创建所有关注事件的描述符集合,会创建读事件、写事件以及异常事件三类事件描述符集合。
2.调用低层提供的select()函数,等待事件发生。
3.轮询所有事件描述符集合中的每一个事件描述符,检查是否有相应的事件发生,如果有,就进行处理。

poll库
poll库是对select的优化实现,和select步骤基本相同。
区别在于poll只会创建一个集合,在每个描述符对应的结构上分别设置读事件、写事件或者异常事件。

epoll库
epoll是一种更加高效的方式,它把描述符列表的管理交给内核负责。
1.epoll库通过相关调用通知内核创建一个有N个描述符的事件列表。
2.给这些描述符设置所关注的事件,并把它添加到内核的事件列表中,也可以通过相关调用对事件列表中的描述符进行修改和删除。
3.某一事件发生后,内核将发生事件的描述列表上报给epoll库,之后就能进行处理了。

Nginx对linux平台提供的事件驱动模型
目前主要的有kqueue模型、/dev/poll模型和eventport模型等。

Nginx的进程

Nginx会产生三类进程

  • 主进程:与外界通讯和对内部其他进程进行管理。
  • 工作进程:进行进程初始化、模块调用和请求处理等工作。
  • 用于为缓存文件建立索引的进程:在Nginx启动一段时间后,对本地缓存内容重建索引,保证缓存文件的快速访问。

Nginx中进程的通信都是通过通道机制来实现的。
channel通道 ——>缓冲区(bytebuffer)——>channel通道
|
先write(),后read()

  • Channel通道:用于应用程序与操作系统进行交互的渠道。
  • buffer缓冲区:保证每个通道的读写速度。
  • Selector选择器:实现Channel与指定的I/O事件进行绑定。

在这里插入图片描述

文章分类
后端
文章标签