Nginx如何实现高性能和可扩展性

Owen Garrett是Nginx公司的产品总监,他在Nginx的官方博客上发表了一篇博文,说明了是哪些设计决策使得NGINX产品具备一流的性能和扩展能力。

NGINX的整体架构的特点是由一组进程协同工作:

  • 主进程:负责执行特权操作,如阅读配置文件、绑定套接字、创建/通知协调(Signalling)子进程。
  • 工作进程:负责接收和处理连接请求,读取和写入磁盘,并与上游服务器通信。当NGINX处于活跃状态时,只有工作进程是忙碌的。
  • 缓存加载器进程:负责将磁盘高速缓存加载到内存中。这个进程在启动时运行后随即退出。
  • 缓存管理器进程:负责整理磁盘缓存的数据保证其不越界。这个进程会间歇性运行。

NGINX能够实现高性能和可扩展性的关键取决于两个基本的设计选型:

  • 尽可能限制工作进程的数量,从而减少上下文切换带来的开销。默认和推荐配置是让每个CPU内核对应一个工作进程,从而高效利用硬件资源。
  • 工作进程采用单线程,并以非阻塞的方式处理多个并发连接。

NGINX的每个工作进程通过状态机处理多个连接请求,这个状态机被实现为非阻塞的工作方式:

  • 每个工作进程需要处理若干套接字,包括监听套接字或者连接套接字。
  • 当监听套接字收到新的请求时,会打开一个新的连接套接字来处理与客户端的通信。
  • 当一个事件到达连接套接字时,工作进程迅速完成响应,并转而处理其他任何套接字新收到的事件。

Garrett说,NGINX选择这样的设计,使它从根本上区别于其他Web服务器。通常的Web服务器会选用将每个连接分配给独立线程的模式,这使得多个连接的处理非常容易,因为每个连接可以被认为是包含多个步骤的一个线性序列,但这样会产生上下文切换的开销。事实上,工作线程大部分的时间处于阻塞的状态,在等待客户端或其它上游服务器。当试图执行I/O等操作的并发连接数/线程数的规模超过一定阈值,或是内存消耗殆尽的时候,上下文切换的成本就显现出来了。

从另一方面讲,NGINX的设计是不让工作进程阻止网络流量,除非没有任何工作要做。此外,每一个新的连接只消耗很少的资源,仅包括一个文件描述符和少量的工作进程内存。

总的来说,NGINX的这种工作模式在系统调优后,它的每个工作进程都能够处理成百上千的HTTP并发连接

原文发布于微信公众号 - nginx(nginx-study)

原文发表时间:2015-06-29

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏HappenLee的技术杂谈

副本机制与副本同步------《Designing Data-Intensive Applications》读书笔记6

首先,如果副本的数据不随时间变化,那么副本的管理是比较简单的:只需要将数据复制到每个节点一次,就OK了。副本管理真正的困难在于对副本数据的修改,这会涉及到很多琐...

973
来自专栏Java技术栈

浅谈大型网站之负载均衡架构

概念 负载均衡,英文名称为Load Balance,其意思就是分摊到多个操作单元上进行执行,例如Web服务器、FTP服务器、企业关键应用服务器和其它关键任务服务...

3106
来自专栏栗霖积跬步之旅

java并发编程的艺术——第一章总结

并发编程的挑战 1.1上下文切换 1.1.1多线程一定快吗 1.1.2测试上下文切换次数和时长 1.1.3如何减少上下文切换 1.1.4减少上下文切换实战   ...

1956
来自专栏码洞

Raft只读操作实现要点

所有的客户端最终都只会链接到Leader。客户端开始时随机挑选一个节点,如果这个节点不是Leader,就通过响应告诉客户端Leader的地址,然后客户端再去连L...

652
来自专栏Java Edge

分布式实践(一) - CAP原则

如图所示,是我们证明CAP的基本场景,网络中有两个节点N1和N2,可以简单的理解N1和N2分别是两台计算机,他们之间网络可以连通,N1中有一个应用程序A,和一个...

622
来自专栏架构师之路

究竟先操作缓存,还是数据库?

但是,一旦没有命中缓存,或者一旦涉及写操作,流程会比没有缓存更加复杂,这些是今天要分享的话题。

1162
来自专栏Golang语言社区

Golang协程与通道整理

协程goroutine 不由OS调度,而是用户层自行释放CPU,从而在执行体之间切换。Go在底层进行协助实现 涉及系统调用的地方由Go标准库...

3467
来自专栏Golang语言社区

由Go语言并发模型想到游戏服务器并发

这段时间看了一些Go语言相关的东西,发现Go语言的最大特性并发模型类似于C++里面的线程池,正好我们项目服务器也是用的线程池,记录下。   Go语言的并发单位是...

3428
来自专栏Linyb极客之路

性能测试之压测中TPS上不去的几种原因分析

在压力测试中,有时候要模拟大量的用户请求,如果单位时间内传递的数据包过大,超过了带宽的传输能力,那么就会造成网络资源竞争,间接导致服务端接收到的请求数达不到服务...

1495
来自专栏韩伟的专栏

高性能服务器架构思路 :分布式系统概念 ( 三 )

分布式的服务器概念很简单,但是实现起来却比较复杂。因为我们写的程序,往往都是以一个CPU,一块内存为基础来设计的,所以要让多个程序同时运行,并且协调运作,这需要...

6K3

扫码关注云+社区