原来,nginx 是这么回事啊!
nginx 的简单介绍
nginx是什么
在 维基百科 上搜索 nignx 就能得到以下结果:
Nginx 是异步框架的web服务器,也可以用作反向代理、负载平衡器。该软件由伊戈尔·赛索耶夫创建并于2004年首次公开发布。
所以我们想要彻底搞清楚 nginx 是什么,就要先弄懂以下关键词的含义:
- web 服务器
- 反向代理
- 负载平衡器
web服务器与应用服务器
web 服务器是网络服务器的子类,而什么是网络服务器呢? 网络服务器就是网络环境下为客户提供某种服务的专用计算机。
目前网络服务器大致可以分为两类,web 服务器和应用服务器。
web 服务器定义:只负责处理 Http 协议,即用于负责处理相应用户的请求。服务器会从网络中接收 HTTP 请求,然后返回 HTTP 回复给用户。 (奥!有点懂了,这不就是与用户交互的第一战场么,用户所有的请求都会被它接收。)
HTTP 回复一般包含一个 HTML 文件, 有时也可以包含纯文本文件、图像或者其他类型的文件。所以,web服务器也称为 http 服务器。 (HTTP 回复的都是一些静态的资源文件,不需要与数据库打交道。又有点懂了,只要是返回给用户是静态资源文件,就可以通过 web 服务器返回,虽然不清楚为什么要通过 web 服务器将静态资源返回,但 web 服务器的最基本的用途搞明白了。)
接下来,举一个例子,再熟悉一下 web 服务器的基本用途: 假设,在域名为 “asa-zhang.top” 绑定的服务器上装了一个服务器软件,然后将服务器软件的根目录设置为 “/home/public/web”,并在该路径中存放了一个 index.html 。当用户想要访问这个 index.html 文件时,他只需要在浏览器上输入一下 URL 就能进行访问:“http://asa-zhang.top/index.html”
应用服务器:用于存放和运行系统程序的服务器,负责处理程序中的业务逻辑。 (这一听,就感觉不一般,尽然是处理业务逻辑,那必然是要与数据库进行交互的,也就是所谓的后端。)
不过大多数应用服务器都将 Web 服务器作为其不可分割的一部分。这意味着应用服务器可以做任何 Web 服务器所能做的事情。 (应用服务器不仅可以向用户提供业务逻辑处理的结果,还能提供服务器上的静态资源文件)
此外,应用服务器有组件和特性来支持应用级服务,如连接池、对象池、事务支持、消息传递服务等。 (这就是应用服务器相较于web服务器而言,独有的高级功能啊,应用服务器的水还很深啊!)
应用服务器也举一个例子: tomcat 就是应用服务器。我们通常将 java 项目放到tomcat 中去运行。
正向代理与反向代理
代理服务器主要分为两类:正向代理 和 反向代理。
正向代理一般是作为客户端的代理,用于将从互联网上获取的资源返回给一个或多个的客户端,服务端(如Web服务器)只知道代理的IP地址而不知道客户端的IP地址。
举一个不太恰当的例子:正向代理就好比是 向小明妈妈借钱。你知道小明妈妈很有钱,但她不认识你。不过没关系,你和小明很熟,就和小明说:“你能不能借点钱给我,我过两天发工资了还你。我知道你没钱,但我知道你妈妈有钱,你可以跟你妈妈要钱。”
在这个例子里,你自己 就是客户端,小明妈妈 就是服务端, 小明就是正向代理服务器。 客户端 知道 服务端的 IP 地址(你 认识 小明妈妈,还知道她很有钱),但服务端 不知道 客户端的 IP 地址 只知道代理的IP地址(小明妈妈 压根儿就没听说过 你,只知道她的儿子),客户端 与 服务端 靠着 代理通信。
还有通信也都是通过正向代理通信的:科学上网,在校外访问校内资源,网络攻防中的“肉鸡”,等等。
在实际场景中正向代理的主要功能:
- 隐藏真实 IP:上网者也可以通过代理服务器隐藏自己的 IP,免受攻击。但是只一个代理很难保证安全,更安全的方法是利用特定的工具创建代理链
- 突破自身IP访问限制:访问国外站点。科学上网,在校外访问校内资源。
- 等
反向代理:服务器根据客户端的请求,从其关系的一组或多组后端服务器(如Web服务器)上获取资源,然后再将这些资源返回给客户端,客户端只会得知反向代理的IP地址,而不知道在代理服务器后面的服务器集群的存在。
举一个不太恰当的例子:正向代理就好比是 向贷款中心借钱。 你 很穷,还不认识有钱人。不过通过跟人打听,知道了可以向 贷款中心 去借钱。然后,就从 贷款中心 借到了钱。在这个过程中,你不需要知道 贷款中心的钱是从哪里来的,只需要知道,可以从这里借钱,同时,也从这里还钱。
在这个例子里,你自己 就是客户端,贷款中心 就是代理服务器。 客户端只会得知反向代理的IP地址(你 只知道 贷款中心,还知道从这里可以借到钱),而不知道在代理服务器后面的服务器集群的存在(却不需要关心 贷款中心 的钱是从哪里来的。)
在实际场景中反向功能:
- 向客户端隐藏服务器(集群)的IP地址。
- 负载均衡,若服务器集群中有负荷较高者,反向代理通过URL重写,根据连线请求从负荷较低者获取与所需相同的资源或备援。
- 等
负载平衡器
最后了解一下负载平衡器的含义。负载平衡器按照常用的说法叫:负载均衡。这两个词通常情况下,是一个意思。
负载均衡最重要的一个应用是 利用多台服务器 提供单一服务。 主要有以下作用:
- 分摊服务器集群压力 可以将接收到的客户端请求 按照设定好的权重比值 分配到集群中所有的服务器上。
- 保证客户端访问的稳定性 当某一台后台服务器出现故障时,负载平衡器就会将请求转发到另一台服务器上。可以显著提高容错能力。
- 加强服务器安全 反向代理的其中一个作用就是负载均衡,故反向代理的作用也适用于负载平衡器。隐藏服务器的IP地址 以及 内网结构,阻止了用户直接访问后台服务器,使得服务器更加安全。
小节
nginx 的主要功能有三点:
- 作为 web 服务器,当充当web服务器的时候,它的主要职责当有用户想要通过URL访问服务器本地资源时,它就是通过 Http响应的方式,将本地静态资源(http 文件或者图片)返回给用户。
- 反向代理,反向代理的场景也很常见。当服务器中存在多个服务时,希望向外暴露一个端口就可以实现对两个服务的访问,这时,就可以使用nginx作反向代理实现这个需求。
- 负载均衡,这个我们“民用”一般是用不着的。只有当企业中存在服务器集群时,为了分摊服务器集群压力以及保证客户端访问的稳定性,使用 nginx 作负载均衡。 故,当我们需要以上功能时,再使用 nginx。当只有一台服务器,服务器中也只有一个服务时,就没必要使用 nginx 了。
nginx 的优点:
nginx 能做什么,上面已经将基本功能介绍的明明白白了。接下来说一说,nginx 有什么优点,才能从众多的同类产品中脱颖而出。
- nginx 是一个跨平台服务器,在众多操作系统上都能正常运行,如:Linux、Windows、FreeBSD、Solaris、AIX、Mac OS。
- nginx 是使用基于事件驱动架构,使其可以支持百万级别的 TCP 连接。
- nginx 中代码是高度模块化的,再加上非常活跃的开源社区开发的众多第三方模块,让nginx 的功能变得非常的丰富。
第一个跨平台服务器很好理解,那基于事件驱动架构是什么呢?以及 nginx 中的代码是如何高度模块化的,才能出现层出不穷的第三方模块。下面逐一介绍。
基于事件驱动架构
我们经常听说过一句话: "nginx 是基于事件驱动模型的IO多路复用epoll"。 那什么是基于事件驱动模型呢?
基于事件驱动 的感念:
从事件角度说,事件驱动程序的基本结构是由一个 事件收集器、一个事件发送器和 一个事件处理器 组成。事件收集器 专门负责收集所有事件,包括来自用户的(如鼠标、键盘事件等)、来自硬件的(如时钟事件等)和来自软件的(如操作系统、应用程序本身等)。事件发送器负责将收集器收集到的事件分发到目标对象中。事件处理器做具体的事件响应工作。
以上说法,也很好理解,总之就是将整个工作流程按照事件的类型进行划分。这样做的好处就是:当前需要什么事件,就执行该事件,当不需要时,就立马释放该资源。
再来看看 nginx 服务器与传统的服务器有什么区别。为什么相较于传统的来说,基于事件驱动架构的nginx就更快(高并发)呢?
对于传统 web 服务器而言,在 TCP 连接上才往往是基于事件驱动的,TCP 连接一旦建立,在其关闭之前的所有操作都不是事件驱动,而是按照顺序执行每个操作。 这样的缺点就在于 每个请求在连接建立后都将始终占用着系统资源,会造成服务器资源极大的浪费。
Nginx 采用事件驱动架构处理业务的方式与传统的 web 服务器是不同的。它不使用进程或者线程来作为事件,而是将事件细分到执行资源的模块上。只有事件收集、分发器才有资格占用进程资源,它们分发某个事件后,调用事件模块时,才会让事件使用当前占用的进程资源。
我们拿吃饭举一个不太恰当的例子。传统的 web 服务器就好比一个人去饭店吃饭,点了四个菜。在他吃完饭前,这四个菜碟子都被他一直占有着,无法被其他人使用。 nginx 服务器也比作一个人去饭店吃饭,点了四个菜。当他吃某个菜时,这个菜的碟子菜归他占有,其他菜碟子都可以被其他人使用。只要最终吃菜的总量是相等的就行。
虽然不太恰当,但是通过这个例子也可以看出,在计算机中 nginx 这种模式效率更高。
Nginx的事件驱动模型由事件收集器、事件发送器和事件处理器三部分基本单元组成。 事件收集器:负责收集worker进程的各种IO请求; 事件发送器:负责将IO事件发送到事件处理器; 事件处理器:负责各种事件的响应工作。
事件发送器将每个请求放入一个待处理事件列表,使用非阻塞I/O方式调用事件处理器来处理该请求,处理方式称为“多路IO复用方法”。
nginx 的高度模块化
nginx 上述的基于事件驱动架构能有如此出色的高并发效率,离不开 nginx 的高度模块化。
nginx 的架构基础就是高度模块化的设计。在 nginx 中,除了少量的核心代码,其他一切皆为模块。高度模块化形成的“高内聚性,低耦合”会产生很多的好处:1.插拔式编程,需要什么功能,添加什么模块。2. 修改某个模块内的代码,并不会影响其他模块的正常运行。等等。
Nginx 官方共有五大类型的模块:核心模块、配置模块、事件模块、HTTP 模块、mail 模块。Nginx 框架密切相关的是配置模块和核心模块,事件模块是 HTTP 模块和 mail 模块的基础。
Nginx快的原因
上述在介绍 nginx 事件驱动架构中,提到了nginx的事件驱动模型由事件收集器、事件发送器和事件处理器三部分基本单元组成。 最终nginx才能如此有高效的性能。
接下来介绍nginx在计算机中是如何实现的。 它是通过master/worker结构实现的,该结构中包含:一个master进程,以及多个 worker 进程。
master 进程主要有三点作用:
- 生成一个或者多个 worker 进程;
- 监控 worker 进程的运行状态,当 worker 进程异常退出后,会自动启动新的 worker 进程。
- 接收来自外界的信号,向各 worker 进程发送信号,让 worker 进程处理请求。
worker 进程的作用就是处理基本的网络事件。多个 worker 进程之间是对等的,他们同等竞争来自客户端的请求,各进程互相之间是独立的。
结语
对于nginx 的基本介绍,到这里就结束了。本节围绕nginx介绍了以下几点:
- nginx 是什么
- nginx 能做什么
- nginx 的优点是什么
- nginx 的优点在内部是如何体现的
同时还介绍了一些其他知识点:
- web服务器与应用服务器的区别
- 正向代理和反向代理的区别
- 负载均衡的概念
- 基于事件驱动模型的概念
最后,以下是我写这篇文章时,参考的一些文章,假如对于nginx还有什么疑惑时,不妨看看以下参考文章,说不定会有所收获。
我们下期再见!
参考链接:
https://zh.wikipedia.org/wiki/Nginx https://juejin.cn/post/6844904129987526663 https://zhuanlan.zhihu.com/p/34943332 https://mp.weixin.qq.com/s/XoqGvYBabW8YBl9xEeNYZw https://zhuanlan.zhihu.com/p/159298538 https://zhuanlan.zhihu.com/p/96889686 https://zhuanlan.zhihu.com/p/137620709 https://juejin.cn/post/6844904129987526663 https://blog.csdn.net/wangqsse/article/details/105924137