热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

高并发_ngnix高并发的原理实现(转)

本文由编程笔记#小编为大家整理,主要介绍了ngnix高并发的原理实现(转)相关的知识,希望对你有一定的参考价值。英文原文:InsideNG
本文由编程笔记#小编为大家整理,主要介绍了ngnix高并发的原理实现(转)相关的知识,希望对你有一定的参考价值。


 英文原文:Inside NGINX: How We Designed for Performance & Scale

  为了更好地理解设计,你需要了解nginx是如何工作的。NGINX之所以能在性能上如此优越,是由于其背后的设计。许多web服务器和应用服务器使用简单的线程的(threaded)、或基于流程的(process-based)架构, NGINX则以一种复杂的事件驱动(event-driven)的架构脱颖而出,这种架构能支持现代硬件上成千上万的并发连接。

  Inside NGINX infographic涉及了从高层次进程架构的挖掘,到NGINX的单进程处理多连接的图解。本篇文章讲解了这些工作细节。

  设置场景——NGINX进程模型

 技术图片

 

  为了更好地理解设计,你需要了解NGINX是如何工作的。NGINX有一个主进程(master process)(执行特权操作,如读取配置、绑定端口)和一系列工作进程(worker process)和辅助进程(helper process)。

技术图片

 

 

  这个四核服务器内,NGINX主进程创建了4个工作进程和2个缓存辅助进程(cachehelper processes)来管理磁盘内容缓存(on-disk content cache)。

  为什么架构很重要?

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



  • · 可以同时使用更多的计算机内核。

  • · 线程和进程使并行操作很容易实现(例如,同时处理多个连接)。

  进程和线程都消耗资源。它们都使用内存和其他OS资源,导致内核频繁切换(被称作上下文切换(context switch)的操作)。大多数现代服务器可以同时处理数百个小的、活跃的(active)线程或进程,但一旦内存耗尽,或高I/O负载导致大量的上下文切换时,服务器的性能就会严重下降。 对于网络应用,通常会为每个连接(connection)分配一个线程或进程。这种架构易于实现,但是当应用程序需要处理成千上万的并发连接时,这种架构的扩展性就会出现问题。

  NGINX是如何工作的?

  NGINX使用一个了可预见式的(predictable)进程模型,调度可用的硬件资源:

  1. 主进程执行特权操作,如读取配置和绑定端口,还负责创建子进程(下面的三种类型)。

  2. 缓存加载进程(cache loader process)在启动时运行,把基于磁盘的缓存(disk-based cache)加载到内存中,然后退出。对它的调度很谨慎,所以其资源需求很低。

  3. 缓存管理进程(cache manager process)周期性运行,并削减磁盘缓存(prunes entries from the disk caches),以使其保持在配置范围内。

  4. 工作进程(worker processes)才是执行所有实际任务的进程:处理网络连接、读取和写入内容到磁盘,与上游服务器通信等。

  多数情况下,NGINX建议每1个CPU核心都运行1个工作进程,使硬件资源得到最有效的利用。你可以在配置中设置如下指令: worker_processes auto,当NGINX服务器在运行时,只有工作进程在忙碌。每个工作进程都以非阻塞的方式处理多个连接,以削减上下文切换的开销。 每个工作进程都是单线程且独立运行的,抓取并处理新的连接。进程间通过共享内存的方式,来共享缓存数据、会话持久性数据(session persistence data)和其他共享资源。

  NGINX内部的工作进程

  每一个NGINX的工作进程都是NGINX配置(NGINX configuration)初始化的,并被主进程设置了一组监听套接字(listen sockets)。

 

  NGINX工作进程会监听套接字上的事件(accept_mutex和kernel socketsharding),来决定什么时候开始工作。事件是由新的连接初始化的。这些连接被会分配给状态机(statemachine)—— HTTP状态机是最常用的,但NGINX还为流(原生TCP)和大量的邮件协议(SMTP,IMAP和POP3)实现了状态机。

技术图片

 


  状态机本质上是一组告知NGINX如何处理请求的指令。大多数和NGINX具有相同功能的web服务器也使用类似的状态机——只是实现不同。

  调度状态机

  把状态机想象成国际象棋的规则。每个HTTP事务(HTTP transaction)都是一局象棋比赛。棋盘的一边是web服务器——坐着一位可以迅速做出决定的大师级棋手。另一边是远程客户端——在相对较慢的网络中,访问站点或应用程序的web浏览器。 然而,比赛的规则可能会很复杂。例如,web服务器可能需要与各方沟通(代理一个上游的应用程序),或者和认证服务器交流。web服务器的第三方模块也可以拓展比赛规则。

  阻塞状态机

  回忆一下我们之前对进程和线程的描述:是一组操作系统可调度的、运行在CPU内核上的独立指令集。大多数web服务器和web应用都使用一个连接/一个进程或一个连接/一个线程的模型来进行这局国际象棋比赛。每个进程或线程都包含一个将比赛玩到最后的指令。在这个过程中,进程是由服务器来运行的,它的大部分时间都花在“阻塞(blocked)”上,等待客户端完成其下一个动作。

 技术图片

 

  1. web服务器进程(web server process)在监听套接字上,监听新的连接(客户端发起的新比赛)。

  2. 一局新的比赛发起后,进程就开始工作,每一步棋下完后都进入阻塞状态,等待客户端走下一步棋。

  3. 一旦比赛结束,web服务器进程会看看客户是否想开始新的比赛(这相当于一个存活的连接)。如果连接被关闭(客户端离开或者超时),web服务器进程会回到监听状态,等待全新的比赛。

  记住重要的一点:每一个活跃的HTTP连接(每局象棋比赛)都需要一个专用的进程或线程(一位大师级棋手)。这种架构非常易于扩展第三方模块(“新规则”)。然而,这里存在着一个巨大的不平衡:一个以文件描述符(file descriptor)和少量内存为代表的轻量级HTTP连接,会映射到一个单独的进程或线程——它们是非常重量级的操作系统对象。这在编程上是方便的,但它造成了巨大的浪费。

  NGINX是真正的大师

  NGINX is a True Grandmaster

  也许你听说过车轮表演赛,在比赛中一个象棋大师要在同一时间对付几十个对手。

 技术图片

 

  Kiril Georgiev在保加利亚首都索菲亚同时对阵360名棋手,最终取得284胜,70平,6负的战绩。

  这就是NGINX工作进程玩“国际象棋”的方式。每一个工作进程都是一位大师(记住:通常情况下,每个工作进程占用一个CPU内核),能够同时对战上百棋手(实际上是成千上万)。

 技术图片

 

  1. 工作进程在监听套接字和连接套接字上等待事件。

  2. 事件发生在套接字上,工作进程会处理这些事件。



  • · 监听套接字上的事件意味着:客户端开始了一局新的游戏。工作进程创建了一个新的连接套接字。

  • · 连接套接字上的事件意味着:客户端移动了棋子。工作进程会迅速响应。

  工作进程从不会在网络上停止,它时时刻刻都在等待其“对手”(客户端)做出回应。当它已经移动了这局比赛的棋子,它会立即去处理下一局比赛,或者迎接新的对手。

  为什么它会比阻塞式多进程的架构更快?

  NGINX的规模可以很好地支持每个工作进程上数以万计的连接。每个新连接都会创建另一个文件描述符,并消耗工作进程中少量的额外内存。每一个连接的额外消耗都很少。NGINX进程可以保持固定的CPU占用率。当没有工作时,上下文切换也较少。

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

  如果想了解更多,请查看由NGINX公司发展和联合创始人副总裁Andrew Alexeev编写的有关NGINX体系结构的文章。

  通过适当的系统调优,NGINX能大规模地处理每个工作进程数十万并发的HTTP连接,并且能在流量高峰期间不丢失任何信息(新比赛开始)。

  配置更新和NGINX升级

  仅包含少量工作进程的NGINX进程架构,使得配置、甚至是二进制文件本身的更新都非常高效。

 技术图片

 

  更新NGINX的配置,是一个非常简单的、轻量级的、可靠的操作。运行nginx –s reload命令即可,该命令会检查磁盘上的配置,并给主进程发送一个SIGHUP信号。

  当主进程接收到SIGHUP信号后,会做两件事:

  1. 重新加载配置,fork一套新的工作进程。这些新的工作进程会立即开始接受连接和处理流量(traffic)(使用新的配置)。

  2. 发出信号,通知旧的工作进程安静地退出。这些旧进程不会再接受新的连接了。只要它们处理的HTTP请求结束了,它们就会干净地关闭连接。一旦所有的连接都被关闭,工作进程也就退出了。

  这个过程会导致CPU占用率和内存使用的一个小高峰,但相比于从活动连接中加载资源,这个小高峰可忽略不计。你可以在一秒内重新加载配置多次。极少情况下,一代又一代工作进程等待连接关闭时会出现问题,但即便出现问题,它们也会被立即解决掉。

  NGINX的二进制升级过程更加神奇——你可以飞速地升级NGINX本身,服务器不会有任何的丢连接、宕机、或服务中断等情况。

 技术图片

 

  二进制升级过程与配置更新相似。新的NGINX主进程与原来的主进程并行,它们共享监听套接字。两个进程都是活跃的(active),它们各自的工作进程处理各自的流量(traffic)。然后,你可以通知旧的主进程与其工作进程完美退出。

  在Controlling NGINX中,整个过程有更详细的描述。

  结论

  NGINX的内部图表高度概述了NGINX是如何运作的,但在这简单的解释背后是超过十年的创新与优化。这些创新与优化,使NGINX在多种硬件上表现出良好的性能,同时还具备现代web应用所需要的安全性和可靠性。

  如果你想阅读更多关于NGINX优化的资料,可以看看这些很棒的资源:

  NGINX安装和性能调优(webinar; slides at Speaker Deck)

  NGINX的性能调优

  开源应用架构——NGINX

  NGINX1.9.1套接字切分(Socket Sharding)(使用SO_REUSEPORT套接字选项)


推荐阅读
  • 如何利用Java 5 Executor框架高效构建和管理线程池
    Java 5 引入了 Executor 框架,为开发人员提供了一种高效管理和构建线程池的方法。该框架通过将任务提交与任务执行分离,简化了多线程编程的复杂性。利用 Executor 框架,开发人员可以更灵活地控制线程的创建、分配和管理,从而提高服务器端应用的性能和响应能力。此外,该框架还提供了多种线程池实现,如固定线程池、缓存线程池和单线程池,以适应不同的应用场景和需求。 ... [详细]
  • 在探讨Hibernate框架的高级特性时,缓存机制和懒加载策略是提升数据操作效率的关键要素。缓存策略能够显著减少数据库访问次数,从而提高应用性能,特别是在处理频繁访问的数据时。Hibernate提供了多层次的缓存支持,包括一级缓存和二级缓存,以满足不同场景下的需求。懒加载策略则通过按需加载关联对象,进一步优化了资源利用和响应时间。本文将深入分析这些机制的实现原理及其最佳实践。 ... [详细]
  • 本文详细介绍如何使用Netzob工具逆向未知通信协议,涵盖从基本安装到高级模糊测试的全过程。通过实例演示,帮助读者掌握Netzob的核心功能。 ... [详细]
  • 秒建一个后台管理系统?用这5个开源免费的Java项目就够了
    秒建一个后台管理系统?用这5个开源免费的Java项目就够了 ... [详细]
  • Juval Löwy主张,每个类都应被视为服务,这并非是为了让服务无处不在,而是因为微服务是经过深思熟虑后系统分解的自然结果。在他的设计和构建的系统中,这种理念有助于提高模块化、可维护性和扩展性。通过将每个类视为独立的服务,系统能够更好地应对复杂性,实现更灵活的部署和更高的性能。 ... [详细]
  • 观察 | 求职体验:收到录用通知的公司通常不深究技术细节,而那些详细追问的公司往往没有后续进展
    观察 | 求职体验:收到录用通知的公司通常不深究技术细节,而那些详细追问的公司往往没有后续进展 ... [详细]
  • Cookie学习小结
    Cookie学习小结 ... [详细]
  • 高端存储技术演进与趋势
    本文探讨了高端存储技术的发展趋势,包括松耦合架构、虚拟化、高性能、高安全性和智能化等方面。同时,分析了全闪存阵列和中端存储集群对高端存储市场的冲击,以及高端存储在不同应用场景中的发展趋势。 ... [详细]
  • 本文回顾了作者初次接触Unicode编码时的经历,并详细探讨了ASCII、ANSI、GB2312、UNICODE以及UTF-8和UTF-16编码的区别和应用场景。通过实例分析,帮助读者更好地理解和使用这些编码。 ... [详细]
  • 单片微机原理P3:80C51外部拓展系统
      外部拓展其实是个相对来说很好玩的章节,可以真正开始用单片机写程序了,比较重要的是外部存储器拓展,81C55拓展,矩阵键盘,动态显示,DAC和ADC。0.IO接口电路概念与存 ... [详细]
  • 您的数据库配置是否安全?DBSAT工具助您一臂之力!
    本文探讨了Oracle提供的免费工具DBSAT,该工具能够有效协助用户检测和优化数据库配置的安全性。通过全面的分析和报告,DBSAT帮助用户识别潜在的安全漏洞,并提供针对性的改进建议,确保数据库系统的稳定性和安全性。 ... [详细]
  • 服务器部署中的安全策略实践与优化
    服务器部署中的安全策略实践与优化 ... [详细]
  • 深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案
    深入剖析Java中SimpleDateFormat在多线程环境下的潜在风险与解决方案 ... [详细]
  • 深入解析CAS机制:全面替代传统锁的底层原理与应用
    本文深入探讨了CAS(Compare-and-Swap)机制,分析了其作为传统锁的替代方案在并发控制中的优势与原理。CAS通过原子操作确保数据的一致性,避免了传统锁带来的性能瓶颈和死锁问题。文章详细解析了CAS的工作机制,并结合实际应用场景,展示了其在高并发环境下的高效性和可靠性。 ... [详细]
  • 求助:在CentOS 5.8系统上安装PECL扩展遇到问题
    在 CentOS 5.8 系统上尝试安装 APC 扩展时遇到了问题,具体表现为 PECL 工具无法正常工作。为了确保顺利安装,需要解决 PECL 的相关依赖和配置问题。建议检查 PHP 和 PECL 的版本兼容性,并确保所有必要的库和开发工具已正确安装。此外,可以尝试手动下载 APC 扩展的源代码并进行编译安装,以绕过 PECL 工具的限制。 ... [详细]
author-avatar
低调的小男2502928607
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有