Nginx 教程:了解架构(操作模式、处理、缓存)
用于处理并发连接的传统基于进程或线程的模型涉及使用单独的进程或线程来处理每个连接并阻塞网络或 I/O 操作。根据应用程序的不同,这在内存和 CPU 消耗方面可能非常低效。创建单独的进程或线程需要准备新的运行时环境,包括分配堆和堆栈内存以及创建新的执行上下文。创建这些项目还会使用额外的 CPU 时间,这可能会导致性能下降,因为线程会围绕太多上下文切换。所有这些复杂情况都发生在 Apache 等较旧的 Web 服务器架构中。它是提供丰富的通用应用程序功能和使用优化的服务器资源之间的折衷。
nginx从一开始就是一个专门的工具,为了实现更高的性能,更集约、更经济地使用服务器资源,同时实现网站的动态发展,所以采用了不同的模型。它实际上是受到各种操作系统中先进事件机制不断发展的启发。开发产生了模块化、事件驱动、异步、单线程、非阻塞架构的 nginx 代码库。
nginx 使用了大量的重用和事件通知,并且专门针对特定任务分离进程。连接在有限数量的单线程进程(称为工作线程 (worker))的高效运行周期中进行处理。对于每个作业(worker),nginx 每秒可以处理数千个并发连接和请求。
代码结构
nginx job(worker)代码包含基础模块和功能模块。基本上,nginx 负责维护严格的执行周期,并在请求处理的每个阶段执行模块代码的适当部分。模块构成了大部分表示层和应用程序层功能。模块读取和写入网络和存储、转换内容、执行出站过滤、实现服务器端摄取操作以及在调用代理时将请求转发到上游服务器。
nginx 的模块化架构允许开发人员经常扩展 Web 服务器功能,而无需更改 nginx 核心。 nginx 模块略有不同,即主模块、事件模块、阶段处理程序、协议、变量处理程序、过滤器、上游和负载均衡器。 nginx不支持动态加载模块;即模块在构建阶段与内核一起编译。
为了处理与接受、管理和管理网络连接以及内容检索相关的各种任务,nginx 使用事件通知机制以及针对 Linux、Solaris 和基于 BSD 的操作系统的一些磁盘 I/O 性能改进,例如:kqueue、 epoll 和事件端口。目标是向操作系统提供尽可能多的提示,以便及时异步反馈有关传入和传出流量、磁盘操作、读或写槽、超时等的信息。对于 nginx 运行的每个基于 Unix 的操作系统,各种多路复用方法和高级 I/O 操作的使用都经过了大量优化。
Nginx 架构的高级概述如下图所示 –
![]()
工作模式
如前所述,nginx 不会为每个连接创建进程或线程。相反,工作进程 (worker) 进程从共享侦听套接字接收新请求,并在每个工作进程 (worker) 内执行高效的启动循环来处理 1000 个作业中的每一个作业。 (员工)。与Nginx job(worker)没有特殊的仲裁或分配;这项工作(worker)是由操作系统的内核机制完成的。启动时创建一组初始侦听套接字。然后,工作人员 (worker) 在处理 HTTP 请求和响应时不断接收、读取和写入套接字。
运行循环是 nginx 工作程序 (worker) 代码中最复杂的部分。它涉及到全面的内部调用,并且严重依赖异步任务处理的思想。异步操作是通过模块化、事件通知、回调的广泛使用和微调计时器来实现的。一般来说,主要原则是尽可能的非阻塞。 nginx 仍会阻塞的唯一情况是工作进程 (worker) 进程没有足够的磁盘空间。
由于 nginx 不连接进程或线程,所以内存使用非常保守,大多数情况下非常高效。 nginx 还可以节省 CPU 周期,因为进程或线程没有连续的创建-销毁模式。 Nginx 的工作是检查网络和存储状态,初始化新连接,将其添加到运行循环中,并异步处理它直到完成,此时连接将被重新分配并从运行循环中删除。结合系统调用(sysCall)的精确实现和支持接口(如pool和slab极端工作负载中等到低CPU占用率。
一些对于磁盘使用情况和 CPU 负载模式,应调整 nginx 作业的数量 (worker)。以下是一些基本规则: 系统管理员应为其工作负载尝试多种配置。一般建议可能是:如果负载模式是 CPU 密集型的,例如处理大量 TCP/IP、执行 SSL 或压缩,则 nginx 作业的数量(worker)应与 CPU 核心数相匹配;如果负载主要与磁盘 I/O 相关,例如通过存储或重型代理服务不同的内容集合 - 工作线程数量 (worker) 可以是核心数量的一到两倍。一些工程师根据单个存储单元的数量来选择工作人员的数量(worker),但这种方法的有效性取决于磁盘存储的类型和配置。
nginx 开发人员将在即将发布的版本中解决的主要问题之一是如何避免磁盘 I/O 中的大多数死锁。目前,如果没有足够的存储性能来服务特定作业 (worker) 的磁盘操作,worker (worker) 仍然可以阻止从磁盘读取/写入。有许多机制和配置文件指令可以缓解此类磁盘 I/O 阻塞情况。请注意,sendfile 和 AIO 等选项的组合通常可以为磁盘性能提供很大的余量。 Nginx 服务器的安装应根据数据集、Nginx 可用的内存量以及底层存储架构来规划。
现有工作人员 (worker) 模式的另一个问题与对嵌入式脚本的有限支持有关。一种使用标准 nginx 发行版,仅支持嵌入 Perl 脚本。简单解释:主要问题是嵌入脚本可能阻止任何操作或意外退出。这两种类型的行为都会立即导致工作者 (worker) 状况,同时影响数千个连接。有计划做更多的工作(worker)让nginx嵌入脚本更简单、更可靠、更适合更广泛的应用。
nginx进程角色
nginx在内存中运行多个进程;有一个主进程和几个工作进程(worker)进程。还有一些特殊用途的进程,特别是缓存加载器和缓存管理器。所有进程都是单线程 nginx 版本1.x。所有进程主要使用共享内存机制进行进程间通信。 root 进程以用户 root 身份运行。缓存加载器、缓存管理器和工作线程 (worker) 以非特权用户身份运行。
主程序负责以下任务: 缓存加载器进程负责检查磁盘缓存项并使用缓存元数据填充 nginx 的内存数据库。基本上,缓存加载器准备一个 nginx 实例来处理已经存储在磁盘上专门分配的目录结构中的文件。它遍历目录,检查缓存内容元数据,更新共享内存中的相关条目,并在一切都干净并准备好使用时退出。 Nginx 缓存是以文件系统中分层数据存储的形式实现的。缓存键是可配置的,并且可以使用各种特定于查询的参数来控制缓存。缓存键和缓存元数据存储在共享内存段中,并由缓存加载器、缓存管理器和工作线程 ( 内容缓存过程如下:当nginx从上游服务器读取响应时,内容首先写入缓存目录结构之外的临时文件中。当nginx处理完请求后,它会重命名临时文件并将其移动到缓存目录。如果代理使用的临时文件目录位于不同的文件系统上,则文件将被复制,因此建议将临时文件目录和缓存目录保留在同一文件系统上。如果需要显式清除缓存目录结构,从缓存目录结构中删除文件也是非常安全的。Nginx 有第三方扩展可以远程管理缓存内容,并且计划开展更多工作将此功能集成到主发行版中。读取和验证配置 )进程接收、处理和管理客户端连接,提供反向代理和过滤功能,并执行几乎所有其他 nginx 功能。在监控 nginx 实例的行为方面,系统管理员应该重点关注工作进程(worker)进程,因为这些进程反映了 Web 服务器的实际日常操作。
缓存管理器主要负责缓存过期和失效。它在 nginx 正常运行期间保留在内存中,并在发生故障时重新启动主进程。 Nginx 缓存简介
worker) 访问。目前,除了操作系统的虚拟文件系统机制提供的优化之外,内存中的文件不会被缓存。每个缓存的响应都放置在文件系统中的不同文件中。层次结构(级别和命名详细信息)是通过 nginx 配置指令控制的。当响应写入缓存目录结构时,文件路径和名称源自代理 URL 的 MD5 哈希值。
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
code前端网