从高级别处理架构下以说明NGINX如何处理一个单一的过程中的多个连接

图片[1]-从高级别处理架构下以说明NGINX如何处理一个单一的过程中的多个连接-4747i站长资讯

NGINX 在网络性能方面处于领先地位,这一切都归功于软件的设计方式。虽然许多 Web 服务器和应用程序服务器使用简单的基于线程或基于进程的架构,但 NGINX 凭借复杂的事件驱动架构脱颖而出,使其能够扩展到现代硬件上的数千个并发连接。

NGINX 信息图从高级处理架构向下钻取,以说明 NGINX 如何在单个进程中处理多个连接。这个博客详细解释了一切是如何运作的。

设置场景——NGINX 进程模型

图片[2]-从高级别处理架构下以说明NGINX如何处理一个单一的过程中的多个连接-4747i站长资讯

为了更好地理解这种设计,你需要了解 NGINX 是如何运作的。NGINX 有一个主进程(执行特权操作,如读取配置和绑定到端口)和许多工作进程。

# service nginx restart
* Restarting nginx
# ps -ef --forest | grep nginx
root     32475     1  0 13:36 ?        00:00:00 nginx: master process /usr/sbin/nginx 
                                                -c /etc/nginx/nginx.conf
nginx    32476 32475  0 13:36 ?        00:00:00  _ nginx: worker process
nginx    32477 32475  0 13:36 ?        00:00:00  _ nginx: worker process
nginx    32479 32475  0 13:36 ?        00:00:00  _ nginx: worker process
nginx    32480 32475  0 13:36 ?        00:00:00  _ nginx: worker process
nginx    32481 32475  0 13:36 ?        00:00:00  _ nginx: cache manager process
nginx    32482 32475  0 13:36 ?        00:00:00  _ nginx: cache loader process

在这个四核服务器上,NGINX 主进程创建了四个工作进程和几个缓存助手来管理磁盘内容缓存。

为什么架构很重要?

任何 Unix 应用程序的基础都是线程或进程。(从 Linux 操作系统的角度来看,线程和进程几乎相同;主要区别在于它们共享内存的程度。)线程或进程是操作系统可以安排在 CPU 上运行的一组独立指令。核。大多数复杂的应用程序并行运行多个线程或进程,原因有两个:

进程和线程消耗资源。它们每个都使用内存和其他操作系统资源,并且需要在内核之间交换(称为上下文切换)。大多数现代服务器可以同时处理数百个小型活动线程或进程,但是一旦内存耗尽或高 I/O 负载导致大量上下文切换,性能就会严重下降。

设计网络应用程序的常用方法是为每个连接分配一个线程或进程。该架构简单且易于实现,但当应用程序需要处理数千个同时连接时,它无法扩展。

NGINX 是如何工作的?

NGINX 使用可预测的进程模型,该模型针对可用的硬件资源进行了调整:

在大多数情况下,建议使用 NGINX 配置(每个 CPU 内核运行一个工作进程)以最有效地使用硬件资源。您可以通过在指令上设置 auto 参数来配置它:

worker_processes auto;

当 NGINX 服务器处于活动状态时,只有工作进程处于忙碌状态。每个工作进程以非阻塞方式处理多个连接,减少了上下文切换的次数。

每个工作进程都是单线程的,并且独立运行以获取新连接并处理它们。进程可以使用共享内存进行通信,以共享缓存数据、会话持久性数据和其他共享资源。

NGINX 进程内部

图片[3]-从高级别处理架构下以说明NGINX如何处理一个单一的过程中的多个连接-4747i站长资讯

每个 NGINX 工作进程都使用 NGINX 配置进行初始化,并且主进程提供一组侦听套接字

NGINX 工作进程首先等待侦听套接字(和内核套接字分片)上的事件。事件由新的传入连接启动。这些连接被分配给状态机 – HTTP 状态机是最常用的,但 NGINX 也为流式传输(原始 TCP)流量和许多邮件协议(SMTP、IMAP 和 POP3))实现状态机。

图片[4]-从高级别处理架构下以说明NGINX如何处理一个单一的过程中的多个连接-4747i站长资讯

状态机本质上是一组指令,告诉 NGINX 如何处理请求。大多数执行与 NGINX 相同功能的 Web 服务器都使用类似的状态机——不同之处在于实现。

调度状态机

将状态机视为国际象棋规则。每个 HTTP 事务都是一盘棋。棋盘的一侧是网络服务器——一个可以很快做出决定的大师。另一端是远程客户端,即通过相对较慢的网络访问站点或应用程序的 Web 浏览器。

但是,游戏规则可能非常复杂。例如,Web 服务器可能需要与其他方通信(代理上游应用程序)或与身份验证服务器通信。Web 服务器中的第三方模块甚至可以扩展游戏规则。

阻塞状态机

回想一下我们对进程或线程的描述,它是一组独立的指令,操作系统可以安排这些指令在 CPU 内核上运行。大多数 Web 服务器和 Web 应用程序使用每个连接的进程或每个连接的线程模型来玩国际象棋游戏。每个进程或线程都包含从头到尾玩游戏的指令。当服务器运行进程时,它大部分时间都在“阻塞”——等待客户端完成下一个动作。

图片[5]-从高级别处理架构下以说明NGINX如何处理一个单一的过程中的多个连接-4747i站长资讯

Web 服务器进程在侦听套接字上侦听新连接(客户端发起的新游戏)。当它得到一个新游戏时,它会玩那个游戏,在每次阻止后等待客户端响应。游戏结束后,Web 服务器进程可能会等待看客户端是否要开始新游戏(这对应于保持连接)。如果连接关闭(客户端消失或发生超时),则 Web 服务器进程返回以侦听新游戏。

要记住的重要一点是,每个活动的 HTTP 连接(每个国际象棋游戏)都需要一个专用的进程或线程()。该架构简单且易于使用第三方模块(“新规则”)进行扩展。然而,这有一个巨大的不平衡:一个相当轻量级的 HTTP 连接,由一个文件描述符和少量内存表示,映射到一个单独的线程或进程,这是一个非常重的 OS 对象。这是一种编程方便,但很浪费。

NGINX是真正的大师

也许你听说过一个棋手同时对战几十个对手的并发表演游戏?

图片[6]-从高级别处理架构下以说明NGINX如何处理一个单一的过程中的多个连接-4747i站长资讯

基里尔在保加利亚索非亚与 360 人同时下棋。他的最终成绩是284胜70平6负。

这就是 NGINX 工作进程充当“棋子”的方式。每个工人(请记住 – 每个 CPU 核心通常只有一个工人)是大师,可以同时玩数百(实际上是数十万)游戏。

图片[7]-从高级别处理架构下以说明NGINX如何处理一个单一的过程中的多个连接-4747i站长资讯

一个工作单元等待监听和连接套接字的事件。事件发生在套接字上,工作人员处理它们:监听套接字上的事件表明客户端已经开始了新的国际象棋游戏。创建一个新的连接套接字。已连接套接字上的事件表明客户端已采取新操作。及时响应。永远不要阻止网络流量,而是等待其“对手”(客户端)响应。动作完成后立即进入其他游戏等待动作处理,或者欢迎新玩家进入游戏。为什么这比阻塞多进程架构更快?

NGINX 可以很好地扩展以支持每个工作进程数十万个连接。每个新连接都会创建另一个文件描述符,并在工作进程中消耗少量额外内存。每个连接几乎没有额外的开销。NGINX 进程可以保持固定在 CPU 上。上下文切换相对不频繁配置高速缓存是为了解决,并且在没有工作可做时发生。

在阻塞的每进程连接方法中,每个连接都需要大量额外的资源和开销,并且上下文切换(从一个进程切换到另一个进程)非常频繁。

有关更详细的解释,请查看 NGINX, Inc. 的开发副总裁兼联合创始人撰写的有关 NGINX 架构的文章。

通过适当的系统调优,NGINX 可以扩展为每个工作进程处理数十万个并发 HTTP 连接,并且可以在不漏掉任何一个节拍的情况下吸收流量峰值(大量新游戏涌入)。

更新配置和升级 NGINX

NGINX 的进程架构拥有少量工作进程,因此可以非常高效地更新配置,甚至包括 NGINX 二进制文件本身。

图片[8]-从高级别处理架构下以说明NGINX如何处理一个单一的过程中的多个连接-4747i站长资讯

更新 NGINX 配置是一个非常简单、轻量且可靠的操作。它通常只是意味着运行 nginx-,它检查磁盘上的配置并向主进程发送信号。

当主进程接收到它时,它会做两件事:

重新加载配置并派生一组新的工作进程。这些新的工作进程立即开始接受连接和处理流量(使用新的配置设置)。指示旧的工作进程正常退出。工作进程停止接受新连接。在每个当前的 HTTP 请求完成后,工作进程干净地关闭连接(即,不是持久的)。一旦所有连接都关闭,工作进程将退出。

此重新加载过程可能会导致 CPU 和内存使用量的小幅增加,但与从活动连接加载资源相比配置高速缓存是为了解决,这通常是难以察觉的。您可以每秒多次重新加载配置(许多 NGINX 用户正是这样做的)。当有许多代 NGINX 工作进程等待连接关闭时,即使这些连接很快解决,问题也很少出现。

NGINX 的二进制升级过程实现了高可用性的圣杯——您可以在不丢失连接、停机或服务中断的情况下即时升级您的软件。

图片[9]-从高级别处理架构下以说明NGINX如何处理一个单一的过程中的多个连接-4747i站长资讯

二进制升级过程类似于正常的重新加载配置方法。一个新的 NGINX 主进程与原来的主进程并行运行,它们共享监听套接字。两个进程都处于活动状态,它们各自的工作进程处理流量。然后,您可以向旧主机及其工作人员发出信号以优雅地退出。

整个过程在“控制 NGINX”中有更详细的描述。

综上所述

此内部 NGINX 信息图提供了 NGINX 功能的高级概述,但其背后的简单解释是,十多年的创新和优化使 NGINX 能够在各种硬件上提供最佳性能,同时保持安全和可靠性现代 Web 应用程序要求。

(本文由文舒奇武翻译自欧文的文章《NGINX: How We for & Scale》,转载请注明出处,原文链接:

)

文章来源:http://www.toutiao.com/a6941190349259883016/

------本页内容已结束,喜欢请分享------

感谢您的来访,获取更多精彩文章请收藏本站。

© 版权声明
THE END
喜欢就支持一下吧
点赞14 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片