Nginx,最强单体之一

本文涉及的产品
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: Nginx是一款高性能的HTTP Web服务器、反向代理、内容缓存及负载均衡器,由伊戈尔·赛索耶夫开发并开源。它采用多进程和I/O多路复用技术,支持高并发和高效处理请求,广泛应用于各大互联网公司。Nginx不仅具备基本的HTTP服务功能,如静态文件处理、反向代理和负载均衡,还支持高级特性如SSL、HTTP/2、动静分离等。其架构设计使其在性能、可靠性、扩展性等方面表现出色,成为Web技术学习和应用的首选工具之一。本文将分两部分介绍Nginx的架构及其原生常用功能。

Hi~,各位读者朋友们,感谢您阅读到本文,我是笠泱,Nginx是学习web技术无论如何也绕不开的应用,也是笔者个人认为学习web技术最好的切入点,原本这期标题笔者想写“Nginx,最强复合型单体”,但想想还有Redis、Kafka、Zookeeper等优秀中间件,逻辑上得严谨所以加上之一,但Nginx绝对是所有IT技术人员都需要了解的一款中间件,它在生产实际中应用十分广泛。本篇笔者计划分两部分,第一部分介绍下Nginx的架构,为啥它能做到高性能高并发?第二部分介绍下原生Nginx常用功能,阅读本文大约需要10分钟。

什么是Nginx

我们先来看Nginx官网(https://nginx.org)对Nginx的原文定义:nginx ("engine x") is an HTTP web server, reverse proxy, content cache, load balancer, TCP/UDP proxy server, and mail proxy server. Originally written by Igor Sysoev and distributed under the 2-clause BSD License. Enterprise distributions, commercial support and training are available from F5, Inc.

笔者用自己的话翻译和拓展官网原文描述:nginx ("engine x") 是一款 HTTP Web服务器, 反向代理, 内容缓存, 负载均衡器, TCP/UDP 代理服务器和邮件代理服务器, 最初由是由伊戈尔·赛索耶夫(Igor Sysoev,俄罗斯人)使用C语言为俄罗斯访问量第二的Rambler.ru站点开发的,并根据 2-clause BSD 许可进行分发,第一个公开版本0.1.0发布于2004年10月4日,另外值得一提的是伊戈尔·赛索耶夫将Nginx的源码进行了开源,这也为Nginx的发展提供了良好的保障。

上图为Nginx之父伊戈尔·赛索耶夫,源于https://www.163.com/dy/article/F0D6CSAG05315PUD.html

官网对Nginx的赞许还是略显保守,Nginx的功能远不止上述那些,得益于Nginx的可扩展模块,Nginx还可以实现API网关、动静分离、正向代理、流媒体服务器、CDN、WAF等系列功能,其最大的特点是占用内存少、并发强、功能多,不愧最强单体之一,业内人送四个字“短小精悍”,在国内能说出名字的网站都使用了Nginx,诸如百度、京东、新浪、网易、腾讯、阿里等等。Nginx在web网站市场份额有多大?先来看W3Techs 给出的一组最新统计数据数据:

上图源于https://w3techs.com/technologies/overview/web_server

再来看下Netcraft公司最新公布的2024年12月数据:

上图源于https://www.netcraft.com/blog/december-2024-web-server-survey

注:Netcraft公司于1994年底在英国成立,多年来一直致力于互联网市场以及在线安全方面的咨询服务,其中在国际上最具影响力的当属其针对网站服务器、SSL市场所做的客观严谨的分析研究,公司官网每月公布的调研数据(Web Server Survey)已成为当今人们了解全球网站数量以及服务器市场分额情况的主要参考依据,时常被诸如华尔街杂志,英国BBC,Slashdot等媒体报道或引用,所以其发布的数据更具备权威性。

上图的OpenResty其实也可以算为Nginx,因为OpenResty是一个基于 Nginx + Lua 的结合体,由此可见Nginx在目前Web市场雄踞一方。

竟然提到HTTP Web服务器,顺便拓展下排第二的Apache,Apache Web Server(官网:https://ws.apache.org/)问世于1995 年 4 月,已发展近30年,同时也有过一段辉煌的业绩。从上图可以看出大概在2014年以前都是市场份额第一的Web服务器。Apache有很多优点,如稳定、开源、跨平台等,但是它出现的时间太久了,在它兴起的年代,互联网的产业规模远远不如今天,所以它被设计成一个重量级的、不支持高并发的Web服务器。在Apache服务器上,如果有数以万计的并发HTTP请求同时访问,就会导致服务器上消耗大量资源,操作系统内核对成百上千的Apache进程做进程间切换也会消耗大量的CUP资源,并导致HTTP请求的平均响应速度降低,这些都决定了Apache不可能成为高性能的Web服务器。反之也促使了Nginx的出现,后文也会提到这两者在架构层的差异。

Nginx的架构

前文有提到Nginx具有性能高、并发强的特点,这与它的架构模式密切相关。Nginx默认采用的是多进程的方式来工作的,当将Nginx启动后,我们通过ps -ef | grep nginx命令可以查看到如下内容:

从上图中可以看到,Nginx后台进程中包含一个master进程和多个worker进程,nginx的进程模型,我们可以通过下图来说明:

那master进程和worker进程具体起着什么作用呢?咱还是先看Nginx官网原文描述:“nginx has one master process and several worker processes. The main purpose of the master process is to read and evaluate configuration, and maintain worker processes. Worker processes do actual processing of requests. nginx employs event-based model and OS-dependent mechanisms to efficiently distribute requests among worker processes. The number of worker processes is defined in the configuration file and may be fixed for a given configuration or automatically adjusted to the number of available CPU cores (see worker_processes).

源于https://nginx.org/en/docs/beginners_guide.html

笔者用自己的话来翻译和拓展官网的原文描述:“nginx的master进程主要用来管理维护worker进程,包含读取和校验配置、接收外界的信息,并将接收到的信号发送给各个worker进程,监控worker进程的状态,当worker进程出现异常退出后,会自动重新启动新的worker进程。而worker进程则是负责实际处理用户请求,各个worker进程之间是平等的并且相互独立,处理请求的机会也是一样的。

另外原文后半句还提到了更重要的信息,nginx 采用基于事件模型和依赖操作系统相关机制,以高效地在工作进程之间分发请求。 worker 进程的数量在配置文件中定义, 可以针对给定配置进行修改,也可以自动调整为可用 CPU 内核数(请参阅 worker_processes)。

什么叫做“基于事件模型和依赖操作系统相关机制(event-based model and OS-dependent mechanisms)”,咱们不妨把话说的再明白点,其实就是网络IO模型,这是一个非常重要的操作系统层面概念,网络IO模型历经BIO(同步阻塞IO)、NIO(同步非阻塞IO)、synchronous I/O multiplexing(多路复用器,如第一版的select、poll,第二版的epoll、kqueue)以及AIO(异步IO,如Windows内核支持的IOCP)演化,其IO性能依照顺序理论上是逐级提升。前文笔者有提到Apache并发能力完全不及Nginx,其中最重要的原因是Apache在开发之初还没有出现更高效的网络IO模型,选择了BIO解决方案,而Nginx采用了基于事件驱动的多路复用器,其并发能力有了质的提升。

笔者最近也在研究网络IO模型,涉及到计算机底层知识,目前笔者还处于一知半解,在这里先挖个坑,等研究较透彻后再来补填上,准备单独开一期文章与读者朋友聊聊。  

上述提到的worker进程数量、网络IO模型都可以在Nginx配置文件中做个性化配置,如下是Nginx一个典型的的配置文件(只截取了全局块和events块):

##全局块 begin##
#配置允许运行Nginx工作进程的用户和用户组
user nginx nginx;
#配置运行Nginx进程生成的worker进程数,设置auto意为Nginx根据服务器CPU的内核数自动调整
worker_processes auto;
#配置Nginx服务器运行对错误日志存放的路径
error_log logs/error.log;
#配置Nginx服务器允许时记录Nginx的master进程的PID文件路径和名称
pid logs/nginx.pid;
#配置Nginx服务是否以守护进程方法启动,默认为on
daemon on;
##全局块 end##
##events块 begin##
events{
  #设置Nginx网络连接序列化
  #这个配置主要可以用来解决常说的"惊群"问题。大致意思是在某一个时刻,客户端发来一个请求连接,Nginx后台是以多进程的工作模式,也就是说有多个worker进程会被同时唤醒,但是最终只会有一个进程可以获取到连接,如果每次唤醒的进程数目太多,就会影响Nginx的整体性能。如果将上述值设置为on(开启状态),将会对多个Nginx进程接收连接进行序列号,一个个来唤醒接收,就防止了多个进程对连接的争抢。
  accept_mutex on;
  #设置Nginx的worker进程是否可以同时接收多个请求
  #如果multi_accept被禁止了,nginx一个工作进程只能同时接受一个新的连接。否则,一个工作进程可以同时接受所有的新连接
  multi_accept on;
  #设置Nginx的worker进程最大的连接数
  #这里的连接数不仅仅包括和前端用户建立的连接数,而是包括所有可能的连接数。另外,number值不能大于操作系统支持打开的最大文件句柄数量,可以通过cat /proc/sys/fs/file-max命令查看。
  worker_connections 1024;
  #设置Nginx哪种事件驱动模型来处理网络请求,该值默认情况下不需要设置,nginx通常会自动根据您的平台和内核版本选择最有效的方法
  use epoll;
  #注意:此处所选择事件处理模型是Nginx优化部分的一个重要内容,method的可选值有select/poll/epoll/kqueue等等,如您使用的是Linux服务器,建议其内核在2.6以上,为了能使用epoll函数来优化Nginx。
}
##events块 end##
...

源于:https://nginx.org/en/docs/events.html 《Nginx Connection processing methods》和https://nginx.org/en/docs/ngx_core_module.html 《Nginx核心模块功能》

Nginx的优势

前文介绍了Nginx架构,我们总结下Nginx的具体优势:

(1)速度更快、并发更高

单次请求或者高并发请求的环境下,Nginx都会比其他Web服务器响应的速度更快。一方面在正常情况下,单次请求会得到更快的响应,另一方面,在高峰期(如有数以万计的并发请求),Nginx比其他Web服务器更快的响应请求。Nginx之所以有这么高的并发处理能力和这么好的性能原因在于Nginx采用了多进程和I/O多路复用(如:epoll)的底层实现

(2)配置简单,扩展性强

Nginx的设计极具扩展性,它本身就是由很多模块组成,这些模块的使用可以通过配置文件的配置来添加。这些模块有官方提供的也有第三方提供的模块,如果需要完全可以开发服务自己业务特性的定制模块。

(3)高可靠性

Nginx采用的是多进程模式运行,其中有一个master主进程和N多个worker进程,worker进程的数量我们可以手动设置,每个worker进程之间都是相互独立提供服务,并且master主进程可以在某一个worker进程出错时,快速去"拉起"新的worker进程提供服务。

(4)热部署

现在互联网项目都要求以7*24小时进行服务的提供,针对于这一要求,Nginx也提供了热部署功能,即可以在Nginx不停止的情况下,对Nginx进行文件升级、更新配置和更换日志文件等功能。

(5)成本低、BSD许可证

BSD是一个开源的许可证,世界上的开源许可证有很多,现在比较流行的有六种分别是GPL、BSD、MIT、Mozilla、Apache、LGPL。Nginx本身是开源的,我们不仅可以免费的将Nginx应用在商业领域,而且还可以在项目中直接修改Nginx的源码来定制自己的特殊要求。这些点也都是Nginx为什么能吸引无数开发者继续为Nginx来贡献自己的智慧和青春,比如OpenRestry 、淘宝的Tengine

Nginx的功能特性及常用功能

原生Nginx提供的基本功能服务从大体上归纳为"基本HTTP服务"、“高级HTTP服务”和"邮件服务"等三大类。

基本HTTP服务

Nginx可以提供基本HTTP服务,可以作为HTTP代理服务器和反向代理服务器,支持通过缓存加速访问,可以完成简单的负载均衡和容错,支持包过滤功能,支持SSL等。

  • 处理静态文件、处理索引文件以及支持自动索引
  • 提供反向代理服务器,并可以使用缓存加上反向代理,同时完成负载均衡和容错
  • 提供对FastCGI、memcached等服务的缓存机制,,同时完成负载均衡和容错
  • 使用Nginx的模块化特性提供过滤器功能。Nginx基本过滤器包括gzip压缩、ranges支持、chunked响应、XSLT、SSI以及图像缩放等。其中针对包含多个SSI的页面,经由FastCGI或反向代理,SSI过滤器可以并行处理
  • 支持HTTP下的安全套接层安全协议SSL
  • 支持基于加权和依赖的优先权的HTTP/2
  • 支持动静分离
  • 支持静态资源的动态压缩和静态压缩
  • 提供浏览器跨域解决方案
  • 提供基于Referer识别的简单防盗链解决方案

高级HTTP服务

  • 支持基于域名和IP的虚拟主机设置
  • 支持HTTP/1.0中的KEEP-Alive模式和管线(PipeLined)模型连接
  • 自定义访问日志格式、带缓存的日志写操作以及快速日志轮转。
  • 提供3xx~5xx错误代码重定向功能
  • 支持重写(Rewrite)模块扩展
  • 支持重新加载配置以及在线升级时无需中断正在处理的请求
  • 支持网络监控
  • 支持FLV和MP4流媒体传输

邮件服务

Nginx提供邮件代理服务也是其基本开发需求之一,主要包含以下特性:

  • 支持IMPA/POP3代理服务功能
  • 支持内部SMTP代理服务功能

拓展sendfile零拷贝技术

笔者在此想多拓展一个关键的IT技术,我们要知道一款软件要实现高性能、高并发其实需要方方面面的优化,在Nginx中就利用到了sendfile零拷贝技术对静态资源进行优化,进一步提升了其性能,咱们先来看Nginx的三个属性配置:

sendfile on;
tcp_nopush on;
tcp_nodelay on;

(1)sendfile:用来开启高效的文件传输模式,默认值sendfile off;

我们先来看下用户(客户端)请求静态资源的过程:客户端通过网络接口向服务端发送请求,操作系统将这些客户端的请求传递给服务器端应用程序,服务器端应用程序会处理这些请求,请求处理完成以后,操作系统还需要将处理得到的结果通过网络适配器传递回去。

sendfile技术处理流程示意图如下:

从上图我们可以看到在未使用sendfile时整个过程发生了2次系统调用,4次数据拷贝,对应4次用户空间和内核空间的切换,一顿操作猛如虎,而结果却是同样一份数据在网络传输给用户之前,在服务器上来回拷贝,可见IO效率较低。

那有没有什么办法优化呢?有,它就是零拷贝技术,常见的优化方案有两种,分别是mmap(内存映射)和sendfile。而sendfile属于更彻底的零拷贝,它是操作系统内核提供的一个方法,光从名字上看,就是专门用于发送文件数据的,应用程序只需要发起系统调用sendfile(),内核会尝试读取磁盘数据然后发送,整个过程发生了1次系统调用,2次数据拷贝,对应2次用户空间和内核空间的切换,虽然还是会有2次数据拷贝但是这2次数据拷贝都不是CPU直接参与,而是利用DMA控制器设备做的拷贝,进而释放CPU性能可以更多地处理用户请求。

关于mmap笔者计划在后续的MQ文章再来详细分析一番,敬请期待!

(2)tcp_nopush:该指令必须在sendfile打开的状态下才会生效,主要是用来提升网络包的传输'效率',默认值为tcp_nopush off;

(3)tcp_nodelay:该指令必须在keep-alive连接开启的情况下才生效,来提高网络包传输的'实时性',默认值tcp_nodelay on;

关于tcp_nopush和tcp_nodelay的形象理解可参考下图:


经过刚才的分析,"tcp_nopush"和”tcp_nodelay“看起来是"互斥的",那么为什么要将这两个值都打开?因为在linux 2.5.9以后的版本中两者是可以兼容的,三个指令都开启的好处是,sendfile可以开启高效的文件传输模式,tcp_nopush开启可以确保在发送到客户端之前数据包已经充分“填满”, 这大大减少了网络开销,并加快了文件发送的速度。 然后,当它到达最后一个可能因为没有“填满”而暂停的数据包时,Nginx会忽略tcp_nopush参数, 然后,tcp_nodelay强制套接字发送数据。由此可知,tcp_nopush可以与tcp_nodelay一起设置,它比单独配置tcp_nodelay具有更强的性能。

本篇结语

通过本文我相信您对Nginx有了大致的认识,也初步感受到了Nginx的架构美学,到此,作为“拥抱云计算”系列第二篇文章,笔者认为差不多了已达到简要介绍Nginx的目标,虽然Nginx还有许多细节值得去学习深究研讨,等后续篇章再娓娓道来吧!

最后,感谢您的阅读!系列文章会同步在微信公众号@云上的喵酱、阿里云开发者社区@云上的喵酱、CSDN@笠泱 更新,您的点赞+关注+转发是我后续更新的动力!

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
相关文章
|
3月前
|
应用服务中间件 Apache 开发工具
nginx服务企业应用
nginx服务企业应用
|
缓存 NoSQL Unix
Nginx 优秀的核心架构设计揭秘
Nginx 优秀的核心架构设计揭秘
260 0
|
应用服务中间件 Linux nginx
Nginx实现高可用
Nginx的高可用指的是在一台Nginx宕机的情况下有其他Nginx去处理请求。
|
负载均衡 应用服务中间件 Linux
Nginx 惊群的原因和解决方案
Nginx 惊群的原因和解决方案
|
缓存 应用服务中间件 nginx
Nginx 动静分离架构 个人笔记
Nginx 动静分离简单来说就是把动态跟静态请求分开,不能理解成只是单纯的把动态页面和静态页面物理分离。严格意义上说应该是动态请求跟静态请求分开,可以理解成使用Nginx 处理静态页面,Tomcat、 Resin 出来动态页面。动静分离从目前实现角度来讲大致分为两种,
129 0
|
缓存 应用服务中间件 数据处理
Nginx - 服务器架构
Nginx - 服务器架构
730 0
Nginx - 服务器架构
|
负载均衡 监控 关系型数据库
Nginx 高可用 的实现
Nginx 高可用 的实现
217 0
|
应用服务中间件 nginx 开发者
Nginx 架构
一、Nginx 模块化设计 高度模块化的设计是 Nginx 的架构基础。Nginx 服务器被分解为多个模块,每个模块就是一个功能模块,只负责自身的功能,模块之间严格遵循“高内聚,低耦合”的原则。 核心模块 核心模块是 Nginx 服务器正常运行必不可少的模块,提供错误日志记录、配置文件解析、事件驱动机制、进程管理等核心功能。
2556 0
|
应用服务中间件 nginx Java
|
Web App开发 应用服务中间件 nginx
nginx的基础应用
nginx的基础应用 一、简介 今天我们将介绍一些nginx的简单应用,启动、停止nginx,重载nginx的配置,nginx配置文件的格式,如何配置nginx服务静态资源,如何配置nginx作为反向代理服务器。
1158 0