Nginx  (engine x)是一个免费、开源、高性能的 HTTP 服务器和反向代理,也可用作负载均衡器 和 HTTP 缓存,以及 IMAP / POP3 代理服务器,以其高性能,稳定性,丰富的功能,简单的配置和低资源消耗而闻名。

Nginx是由伊戈尔·赛索耶夫为俄罗斯访问量第二的Rambler.ru站点(俄文:Рамблер)开发的,第一个公开版本0.1.0发布于2004年10月4日。

其将源代码以类BSD许可证的形式发布,因它的稳定性、丰富的功能集、示例配置文件和低系统资源的消耗而闻名。2011年6月1日,nginx 1.0.4发布。

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:百度、京东、新浪、网易、腾讯、淘宝等。

 

Nginx 官网:http://nginx.org ,nginx-1.17.6.tar.gz (2019-11-19)

Nginx Github:https://github.com/nginx/nginx

Tengine 官网:http://tengine.taobao.org (淘宝)

Tengine Github:https://github.com/alibaba/tengine

 

Tengine (淘宝)

Tengine是由淘宝网发起的Web服务器项目,它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性

Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。

从2011年12月开始,Tengine成为一个开源项目,Tengine团队在积极地开发和维护着它。

Tengine团队的核心成员来自于淘宝、搜狗等互联网企业。

Tengine是社区合作的成果,我们欢迎大家参与其中,贡献自己的力量。

特性

  • 继承Nginx-1.17.3的所有特性,兼容Nginx的配置
  • 支持HTTP的CONNECT方法,可用于正向代理场景;
  • 支持异步OpenSSL,可使用硬件如:QAT进行HTTPS的加速与卸载;
  • 增强相关运维、监控能力,比如异步打印日志及回滚,本地DNS缓存,内存监控等;
  • Stream模块支持server_name指令;
  • 更加强大的负载均衡能力,包括一致性hash模块、会话保持模块,还可以对后端的服务器进行主动健康检查,根据服务器状态自动上线下线,以及动态解析upstream中出现的域名;
  • 输入过滤器机制支持。通过使用这种机制Web应用防火墙的编写更为方便;
  • 支持设置proxy、memcached、fastcgi、scgi、uwsgi在后端失败时的重试次数
  • 动态脚本语言Lua支持。扩展功能非常高效简单
  • 支持按指定关键字(域名,url等)收集Tengine运行状态;
  • 组合多个CSS、JavaScript文件的访问请求变成一个请求
  • 自动去除空白字符和注释从而减小页面的体积
  • 自动根据CPU数目设置进程个数和绑定CPU亲缘性;
  • 监控系统的负载和资源占用从而对系统进行保护;
  • 显示对运维人员更友好的出错信息,便于定位出错机器;
  • 更强大的防攻击(访问速度限制)模块
  • 更方便的命令行参数,如列出编译的模块列表、支持的指令等;
  • 可以根据访问文件类型设置过期时间;
  • ……

 

Nginx 优点特性

Nginx 是一个很强大的高性能Web和反向代理服务,被广泛的应用

正是由于其优秀的架构设计,它具有很多非常优越的特性:

模块化设计、事件驱动架构、请求的多阶段异步处理、管理进程与多工作进程设计、内存池的设计

Nginx 可以在大多数 UnixLinux OS 上编译运行,并有 Windows 移植版

Nginx 的1.4.0稳定版已经于2013年4月24日发布,一般情况下,对于新建站点,建议使用最新稳定版作为生产版本,已有站点的升级急迫性不高。

在连接高并发的情况下,Nginx是Apache服务不错的替代品:Nginx在美国是做虚拟主机生意的老板们经常选择的软件平台之一。

能够支持高达 50,000 个并发连接数的响应,感谢Nginx选择了 epoll and kqueue作为开发模型。

 

一、Nginx  原理架构

Nginx 里有一个 master 进程和多个 worker 进程。

1)master 进程并不处理网络请求,主要负责调度工作进程:加载配置、启动工作进程、非停升级(reload)

2)worker 进程负责处理网络请求与响应,在类 unix 系统上,Nginx 可以配置多个 worker,而每个 worker 进程都可以同时处理 数以千计 的网络请求。

所以,Nginx 启动以后,查看操作系统的进程列表,我们就能看到至少有两个 Nginx 进程(master 和 worker)

master进程主要用来管理worker进程,具体包括如下4个主要功能:

1)接收来自外界的信号,包含客户端、服务端、控制端。

2)向各worker进程发送信号。

3)监控woker进程的运行状态。

4)当woker进程退出后(异常情况下),会自动重新启动新的woker进程。

woker进程主要用来处理基本的网络事件:

1)多个worker进程之间是对等且相互独立的,他们同等竞争来自客户端的请求。

2)一个请求,只可能在一个worker进程中处理,一个worker进程,不可能处理其它进程的请求。

3)worker进程的个数是可以设置的,一般会设置进程数量与机器cpu核数一致

4)nginx为了更好的利用多核特性,具有cpu绑定选项,可以将某一个进程绑定在某一个核上,这样就不会因为进程的切换带来cache的失效。

 

Ngnix 实现高性能

1、事件驱动模型

基于异步及非阻塞的事件驱动模型,可以说是 Nginx 得以获得高并发、高性能的关键因素。

同时也得益于对 Linux、Solaris 及类 BSD 等操作系统内核中事件通知及 I/O 性能增强功 的采用

这一点上和 Netty 类似,底层都是使用的 BSD kqueue、Linux epoll 及 Solaris event ports

 

2、多进程机制

使用多进程的好处:

1)进程之间不共享资源,不需要加锁,减少了使用锁对性能造成的影响,同时降低编程的复杂度,降低开发成本。

2)采用独立的进程,可以让进程互相之间不会影响,如果一个进程发生异常退出时,其它进程正常工作,

3)master 进程则很快启动新的 worker 进程,确保服务不会中断,从而将风险降到最低。

 

3、内存池

为了避免出现内存碎片,减少向操作系统申请内存的次数、降低各个模块的开发复杂度,Nginx 设计了简单的内存池,

它的作用主要是把多次向系统申请内存的操作整合成一次,这大大减少了 CPU 资源的消耗,同时减少了内存碎片。

因此,通常每一个请求都有一个简易的独立内存池(如每个 TCP 连接都分配了一个内存池),而在请求结束时则会销毁整个内存池,把曾经分配的内存一次性归还给操作系统。这种设计大大提高了模块开发的简单些,因为在模块申请内存后不用关心它的释放问题;而且因为分配内存次数的减少使得请求执行的时延得到了降低。

同时,通过减少内存碎片,提高了内存的有效利用率和系统可处理的并发连接数,从而增强了网络性能。

 

4、模块化设计

高度模块化的设计是 Nginx 的架构基础。

Openresty 就是在 Nginx 上引入了 lua 等第三方模块,使得扩展更加方便了。

在 Nginx 中,除了少量的核心代码,其他一切皆为模块,所有模块间是分层次、分类别的

Nginx 官方共有五大类型的模块:核心模块、配置模块、事件模块、HTTP 模块、mail 模块

在上图的 5 种模块中,配置模块和核心模块是与 Nginx 框架密切相关的。

而事件模块则是 HTTP 模块和 mail 模块的基础。HTTP 模块和 mail 模块的“地位”类似,它们都是更关注于应用层面。

 

Nginx 的 worker 进程,包括核心和功能性模块,核心模块负责维持一个运行循环(run-loop),执行网络请求处理的不同阶段的模块功能,

比如:网络读写、存储读写、内容传输、外出过滤,以及将请求发往上游服务器等。

而其代码的模块化设计,也使得我们可以根据需要对功能模块进行适当的选择和修改,编译成具有特定功能的服务器。

 

5、代理(proxy)设计

代理设计,可以说是 Nginx 深入骨髓的设计,无论是对于 HTTP,还是对于 FastCGI、Memcache、Redis 等的网络请求或响应,本质上都采用了 代理机制。

所以,Nginx 天生就是高性能的代理服务器。

 


二、Nginx 模块化设计

高度模块化的设计是 Nginx 的架构基础,包括核心和功能性模块。

Nginx 服务器被分解为多个模块,每个模块就是一个功能模块,只负责自身的功能,模块之间严格遵循 “高内聚,低耦合” 的原则。

1、核心模块

核心模块Nginx 服务器正常运行必不可少 的模块,提供 错误日志记录配置文件解析事件驱动机制进程管理 等核心功能。

 

2、标准HTTP模块

标准 HTTP 模块提供 HTTP 协议解析相关的功能,比如:端口配置网页编码设置HTTP 响应头设置 等等。

 

3、可选HTTP模块

可选 HTTP 模块主要用于 扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,

比如:Flash 多媒体传输、解析 GeoIP 请求、网络传输压缩、安全协议 SSL 支持等。

 

4、邮件服务模块

邮件服务模块 主要用于支持 Nginx 的 邮件服务,包括对 POP3、IMAP 、SMTP 协议的支持。

 

5、第三方模块

第三方模块 是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如:Json 支持、Lua 支持等。

 

三、Nginx的请求方式处理

Nginx 是一个 高性能 的 Web 服务器,能够同时处理 大量的并发请求。

它结合多进程机制和异步机制,异步机制使用的是异步非阻塞方式。

1、多进程机制

服务器每当收到一个客户端时,就有服务器主进程master process)生成一个 子进程worker process)出来和客户端建立连接进行交互,直到连接断开,该子进程就结束了。

使用 进程的好处:

1)各个进程之间相互独立不需要加锁,减少了使用锁对性能造成影响,同时降低编程的复杂度,降低开发成本。

2)采用独立的进程,可以让 进程互相之间不会影响,如果一个进程发生异常退出时,其它进程正常工作,master 进程则很快启动新的 worker 进程,确保服务不会中断,从而将风险降到最低。

缺点是操作系统生成一个 子进程需要进行 内存复制 等操作,在 资源时间 上会产生一定的开销。当有 大量请求 时,会导致 系统性能下降

 

2、异步非阻塞机制

每个 工作进程 使用 异步非阻塞方式,可以处理 多个客户端请求

当某个 工作进程 接收到客户端的请求以后,调用 IO 进行处理,如果不能立即得到结果,就去 处理其他请求(即为 非阻塞);

客户端 在此期间也 无需等待响应,可以去处理其他事情(即为 异步)。

IO 返回时,就会通知此 工作进程;该进程得到通知,暂时 挂起 当前处理的事务去 响应客户端请求

 

四、Nginx 事件驱动模型

Nginx异步非阻塞机制 中,工作进程在调用 IO 后,就去处理其他的请求,当 IO 调用返回后,会 通知工作进程

对于这样的系统调用,主要使用 Nginx 服务器的 事件驱动模型 来实现。

如上图所示,Nginx事件驱动模型事件收集器、事件发送器、事件处理器 三部分基本单元组成。

事件收集器:负责收集 worker 进程的各种 IO 请求;

事件发送器:负责将 IO 事件发送到 事件处理器

事件处理器:负责各种事件的 响应工作

事件发送器 将每个请求放入一个 待处理事件列表,使用非阻塞 I/O 方式调用 事件处理器 来处理该请求。

其处理方式称为 “多路 IO 复用方法”,常见的包括以下三种:select 模型、poll 模型、epoll 模型

 

五、Nginx 进程处理模型

Nginx 服务器使用 master/worker 多进程模式。多线程启动和执行的流程如下:

1)主程序 Master process 启动后,通过一个 for 循环来 接收处理外部信号

2)主进程 通过 fork() 函数产生 worker 子进程,每个子进程 执行一个 for 循环来实现 Nginx 服务器 对事件的接收处理

一般推荐 worker 进程数CPU 内核数 一致,这样一来不存在 大量的子进程 生成和管理任务,避免了进程之间 竞争 CPU 资源进程切换 的开销。

而且 Nginx 为了更好的利用 多核特性,提供了 CPU 亲缘性 的绑定选项,我们可以将某 一个进程绑定在某一个核 上,这样就不会因为 进程的切换 带来 Cache 的失效。

对于每个请求,有且只有一个 工作进程 对其处理。

首先,每个 worker 进程都是从 master 进程 fork 过来。在 master 进程里面,先建立好需要 listensocket(listenfd) 之后,然后再 fork 出多个 worker 进程。

所有 worker 进程的 listenfd 会在 新连接 到来时变得 可读,为保证只有一个进程处理该连接,所有 worker 进程在注册 listenfd 读事件抢占 accept_mutex,抢到 互斥锁 的那个进程 注册 listenfd 读事件,在 读事件 里调用 accept 接受该连接。

当一个 worker 进程在 accept 这个连接之后,就开始 读取请求解析请求处理请求,产生数据后,再 返回给客户端,最后才 断开连接,这样一个完整的请求就是这样的了。我们可以看到,一个请求,完全由 worker 进程来处理,而且只在一个 worker 进程中处理。

Nginx 服务器的运行过程中,主进程工作进程 需要进程交互,交互依赖于 Socket 实现的 管道 来实现。

1、主进程与工作进程交互

这条管道与普通的管道不同,它是主进程 指向 工作进程单向管道,包含主进程向工作进程发出的 指令工作进程 ID 等;

同时 主进程 与外界通过 信号通信;每个 子进程 具备 接收信号,并处理相应的事件的能力。

2、工作进程与工作进程交互

这种交互是和 主进程-工作进程 交互是基本一致的,但是会通过 主进程 间接完成

工作进程 之间是 相互隔离 的,所以当工作进程 W1 需要向工作进程 W2 发指令时,首先找到 W2进程 ID,然后将正确的指令写入指向 W2通道W2 收到信号采取相应的措施。

 

总结

通过这篇文章,我们对 Nginx 服务器的 整体架构 有了一个整体的认识。

包括其 模块化的设计多进程异步非阻塞 的请求处理方式、事件驱动模型 等。

通过这些理论知识,才能更好地领悟 Nginx 的设计思想,对于学习 Nginx 来说有很大的帮助。

 

 

本文转自:

Nginx 原理和架构  (CSDN)

Nginx架构模型分析  (掘金)

浅谈Nginx服务器的内部核心架构设计  (掘金)

深入 Nginx 之架构篇   (segmentfault)

 

 

参考推荐:

Nginx 架构模型深入分析

Nginx 百万并发的优化之道

Nginx location 正则匹配规则

Nginx 配置 Location 指令块

Nginx 配置文件详解

Nginx使用ssl模块配置HTTPS

Nginx Redirect重定向所有子域名到www

Nginx rewrite 隐藏 .php 后缀

LNMP(CentOS+Nginx+Mysql+PHP)服务器环境配置

Nginx 限制单个IP的并发连接数/速度防止恶意攻击/蜘蛛爬虫采集

Nginx 支持动态配置的开源Web服务器

Nginx 配置Apache前端服务器

PHP解决网站大数据大流量与高并发

PHP 高并发下请求 Redis 异常处理

Apache、Nginx、Tomcat 区别

Apache 和 Nginx 对比

Apache 设置禁止访问网站目录

Apache Rewrite 规则 RewriteCond、RewriteRule 参数配置详解

Apache 封禁IP及IP段访问

httpd使用ssl模块配置HTTPS

实用 .htaccess 用法大全

.htaccess绑定域名到子目录

Linux grep 正则表达式