前言
本文会对Nginx的介绍、使用、原理等知识作由浅入深的剖析。如果你只想对Nginx作为反向代理的使用作初步的了解,那么可以只看第一、二章节;如果想对Nginx工作原理、扩展使用等进行深入研究,可以看第三章节。相信本文会对你有所帮助
一、Nginx 基本介绍
1. 了解 Nginx
Nginx(“engine x”)是一个高性能的HTTP和反向代理服务器,特点是占有内存少,并发能力强,事实上Nginx的并发能力确实在同类型的网页服务器中表现较好。 Nginx 专为性能优化而开发,性能是其最重要的考量,实力上表现注重效率,能经受高负载的考验,有报告表明Nginx能支持高达50000个并发连接数。
- 俄罗斯程序员Igor Sysoev于2022年开始
- Nginx是增长最快的Web服务器,市场份额已达33.3%
- 全球使用量排行第二2011年成立商业公司
2. 关于反向代理
Nginx不仅可以做反向代理,实现负载均衡。还能用做正向代理来进行上网等功能。
2.1 正向代理
正向代理:如果把局域网的Internet想象成一个巨大的资源库,则局域网中的客户端要访问Internet,则需要通过代理服务器来访问,这种代理服务就称为正向代理。在客户端(浏览器)配置代理服务,通过代理服务器进行互联网访问。
2.3 反向代理
反向代理:其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,再返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。
2.4 正向代理与反向代理的区别
正向代理与反向代理的区别在于代理的对象不一样,正向代理代理的对象是客户端,反向代理代理的对象是服务端。
- 正向代理即是客户端代理, 代理客户端, 服务端不知道实际发起请求的客户端
- 反向代理即是服务端代理, 代理服务端, 客户端不知道实际提供服务的服务端
3. 负载均衡
客户端发送多个请求到服务器,服务器处理请求,有一些可能要与数据库进行交互,服务器处理完毕后,再将结果返回给客户端。
这种架构模式对于早期的系统相对单一,并发请求相对较少的情况下是比较适合的,成本也低。但是随着访问量和数据量的飞速增长,以及系统业务的复杂度增加,这种架构会造成服务器响应客户端的请求日益缓慢,并发量特别大的时候,还容易造成服务器直接崩溃。很明显这是由于服务器性能的瓶颈造成的问题,那么如何解决这种情况呢?
我们首先想到的可能是升级服务器配置,比如提高CPU执行频率,加大内存等提高服务器的物理性能来解决此问题,但我们知道摩尔定律的日益失效,硬件的性能提升已经不能满足日益提升的需求了。最明显的一个例子,天猫双十一当天,某个热销商品的瞬时访问量是极其庞大的,那么类似上面的系统架构,将机器都增加到现有的顶级物理配置,都是不能够满足需求的,那么怎么办呢?
上面的分析我们去掉了增加服务器物理配置来解决问题的办法,也就是说纵向解决问题的办法行不通了,那么横向增加服务器的数量呢?这时候集群的概念产生了,单个服务器解决不了,我们增加服务器的数量,然后将请求分发到各个服务器上,将原先请求集中到单个服务器上的情况改为将请求分发到多个服务器上,将负载分发到不同的服务器,也就是我们所说的负载均衡。
4. 动静分离
原部署方式:动态资源与静态资源都部署在同一服务器中,这样的方式会使Tomcat有较大压力
动静分离:为了加快网站的解析速度,可以把动态页面和静态页面由不同的服务器来解析,加快解析速度。降低原来单个服务器的压力。 在动静分离下,Tomcat 有比较明显的优化,因为 Tomcat 解析静态很慢。其实原理很好理解,简单来说,使用正则表达式匹配过滤,然后交给不同的服务器。
静态页面一般直接由Nginx来处理,动态页面则是通过反向代理,代理到后端的 Tomcat,然后再做负载均衡,是选择本地静态页面还是后端Tomcat,这由负载均衡配置决定。
动静分离是在负载均衡后做的,例如静态web有多台,动态web有多台,先动静分离,然后在各自集群里做负载均衡、权重等。
关于动静分离的Nginx配置,可见文章:Nginx动静分离详细配置
二、Nginx 基本使用
1. Nginx 常用命令
使用Nginx操作命令前提条件:进入到 nginx/sbin 目录 /usr/local/nginx/sbin
-
查看Nginx版本号:./nginx -v
-
测试Nginx配置:./nginx -t
-
启动Nginx:./nginx
-
关闭Nginx:./nginx -s stop
-
重新加载Nginx配置文件:./nginx -s reload
2. Nginx 配置文件
(1)Nginx配置文件目录:/nginx/conf/nginx.conf
(2)Nginx配置文件的组成
Nginx的配置文件由三部分组成,分别为全局块、events块、http块
2.1 第一部分:全局块
从配置文件开始到 events 块之间的内容,主要会设置一些影响 Nginx 服务器整体运行的配置指令,主要包括配置运行 Nginx 服务器的用户(组)、允许生成的 worker process 数,进程 PID 存放路径、日志存放路径和类型以及配置文件的引入等。
比如上面第一行配置的:worker_processes 1
,这是 Nginx 服务器并发处理服务的关键配置,worker_processes 值越大,可以支持的并发处理量也越多,但是会受到硬件、软件等设备的制约。
2.2 第二部分:events块
events 块设计的指令主要影响 Nginx 服务器与用户的网络连接,常用的设置包括是否开启对多 work process 下的网络连接进行序列化,是否允许同时接收多个网络连接,选取哪种事件驱动模型来处理连接请求,每个 word process 可以同时支持的最大连接数等。
上图中的例子标识每个 work process 支持的最大连接数为 1024。这部分的配置对 Nginx 的性能影响较大,在实际中应该灵活配置。
2.3 第三部分:http块
这一模块是 Nginx 服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里。需要注意的是:http 块也可以包括 http 全局块、server 块。
① http 全局块
http 全局块配置的指令包括文件引入、MIME-TYPE定义、日志自定义、连接超时时间、单链接请求数上限等。
② server 块
这块和虚拟主机有密切关系,虚拟主机从角度看,和一台独立的硬件主机是完全一样的,该技术的产生是为了节省互联网服务器硬件成本。
每个 http 块可以包括多个 server 块,而每个 server 块就相当于一个虚拟主机。
每个 server 块也分为全局 server 块,以及可以同时包含多个 location 块。
- 全局 server 块
最常见的配置是本虚拟主机的监听配置和本虚拟主机的名称或IP配置 - location 块
一个 server 块可以配置多个 location 块。
这块的主要作用是基于 Nginx 服务器接收到的请求字符串(例如server_name/uri-string),对虚拟主机名称(也可以是IP别名)之外的字符串(例如 前面的/uri-string)进行匹配,对特定的请求进行处理。地址定向、数据缓存和应答控制等功能,还有许多第三方模块的配置也在这里进行。
三、Nginx 进阶
1. Nginx 详述
1.1 Nginx 社区分支
- Openresty:作者@agentzh(章宜春)开发的,最大特点是引入了ngx_lua模块,支持使用lua开发插件,且集合了很多丰富的模块以及lua库
- Tengine:主要由淘宝团队开发。特点是融入了因淘宝自身的一些业务带来的新功能(统计QPS、主动健康检查等)
- Nginx官方版本:更新迭代快,且提供免费版本和商业版本。目前大多数使用的是免费版本,核心版本为1.6
1.2 Nginx 源码结构
Nginx 大约含11万行C代码,源代码目录结构:
- core:主干和基础设置,包括链表、数组、字符串解析、MD5库等。定制化开发时候可以直接使用此目录的数据结构
- event:事件驱动模型和不同的IO复用模块
- http:HTTP服务器和模块
- mail:邮件代理服务器和模块
- os:操作系统相关的实现
- misc:杂项
如果我们要开发新http模块,可参考下http中内容,调用core模块的库函数来实现新模块开发
1.3 Nginx 特点
- 反向代理,负载均衡:用的最多也是最基础的特点。最常用的负载均衡算法是轮询,另外还有IP哈希、URL哈希、基于服务器后端响应时间的负载均衡
- 高可靠性,架构模型基于单master多worker模式:master管理所有worker。当worker意外call down,master立即拉取新worker
- 高可扩展性、高度模块化:Nginx 有主流程11个阶段,每个阶段都可以进行独立的专注扩展
- 非阻塞:Nginx非常快,基于纯C实现,即收即发的非阻塞模式
- 事件驱动:支持多种事件驱动,默认采用epoll(最流行最火的)
- 低内存消耗:在刚开始创建内存池,每次请求会取用其中一小块内存,用完即回收(减少了因系统不断开辟内核态内存产生的内存碎片,防止内存泄漏)
- 热部署:不停机的状态下,更新二进制文件与配置,完成升级
1.4 Nginx 更多应用场景
- 静态文件服务器:将静态页面资源(图片、CSS、样式表)与动态服务器分离,存储于不同服务器上,即动静分离
- 反向代理、负载均衡:作为反向代理,以负载多台服务集群
- 安全防御:带有限流、限速等功能
- 智能路由:比如进行灰度测试,A、B两个版本,测A与B的功能,看用户更喜爱哪个。,另外A机房出现问题也可以切换到B机房
- 灰度发布:上面所说的AB测试
- 静态化:动态服务器性能无法承担,
- 消息推送:成本较高,不作多介绍
- 图片实时压缩
- 防盗链:根据配置实现防盗链,比如图片打水印等方式
1.5 Nginx 进程组件角色
-
master 进程
- 监视worker进程的状态
- 当worker进程挂掉后,重启一个新的
- 处理信号和通知worker进程
-
worker 进程
- 处理客户端请求
- 从master进程处获得信号做相应的事情
-
cache loader进程
- 加载缓存索引文件信息,然后退出
-
cache manager进程
- 管理磁盘的缓存大小,超过预定值大小后,根据LRU淘汰数据
2. Nginx 框架模型
-
Client 发送请求到 Nginx:Nginx中存在多个Worker抢占该连接请求,仅有一个会抢占成功并处理该连接,处理完成后返回响应给Client
-
管理员(运维人员) 发送请求到Nginx:比如发送一个reload信号,该请求会被Master进程接收,并交给所有Worker执行相应操作
Client与Nginx交互的详细流程:Master进程启动时,创建socket绑定端口并监听,然后创建多个Worker进程。Worker进程accept来自Client的连接,Client发送请求包至Worker,因为是非阻塞,创建连接后可能由于网络延迟发包较慢而receive多次
2.1 Master 进程的初始化
Master初始化启动时会加载配置文件,创建全局数据结构、共享内存、连接池等,并创建Workers,然后等待接收信号。(特别解释下reload命令,它会使Workers处理完任务后退出,并fork一批新的Workers接收新的请求)
2.2 Worker 进程的初始化
Worker中有各个模块与11个阶段,初始化各个模块,包括进行回调函数、事件模块、定时器的初始化
3. 静态文件请求流程
Client发送请求到Nginx,Nginx初始化连接并建立读事件的回调函数,该函数从TCP中读取客户端发送的数据,读取完成后解析请求行,检验该请求的HTTP合法性(是否有非法字符等),然后解析请求,并执行Nginx的11个阶段。此时进入static_handler函数,在Nginx配置的目录中找寻相应静态资源文件读取进内存,响应Client
4. Upstream设计
Upstream用来解决跨进程访问第三方Server服务器问题,具有以下特点:
- 底层HTTP通信框架非常完善,采用异步非阻塞模式
- 上下游内存零拷贝,节省内存,提升效率(Nginx接收到Client的请求直接发送给后端Server)
- 支持自定义模块开发
5. 反向代理流程
Nginx接收到Client发送的请求,进行解析并进行upstream:初始化upstream请求,连接后端Server发送请求,接收来自Server的响应,最终返回响应给Client
四、Nginx 定制化开发
1. Nginx 模块化设计特点
-
高度抽象的模块接口:所有模块遵循Nginx模块定义规范
-
模块接口简单,具有很高的灵活性:模块之间无关联且独立,对其中一个模块的修改不会干涉到其他模块
-
配置模块的设计:
-
核心模块接口的简单化:event模块存在select poll,http模块、email模块文章来源:https://www.toymoban.com/news/detail-728626.html
-
多层次、多类别的模块设计文章来源地址https://www.toymoban.com/news/detail-728626.html
到了这里,关于学习笔记:代理服务器——Nginx的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!