当前位置:   article > 正文

高性能Web服务器-- Nginx 的架构与安装详解

高性能Web服务器-- Nginx 的架构与安装详解

1.1 Nginx 概述

1.1.1 Nginx简介

Nginx:engine X ,2002年开发,分为社区版和商业版(nginx plus )

2019年3月11日 F5 Networks 6.7亿美元的价格收购

Nginx是免费的、开源的、高性能的HTTP和反向代理服务器、邮件代理服务器、以及TCP/UDP代理服务器。用于解决C10K问题(10K Connections)

Nginx官网:http://nginx.org

nginx的其它的二次发行版:

  • Tengine:由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。从2011年12月开始,Tengine成为一个开源项目官网: http://tengine.taobao.org/

  • OpenResty:基于 Nginx 与 Lua 语言的高性能 Web 平台, 章亦春团队开发,官网:http://openresty.org

1.1.2 Nginx的功能和基础特性
  • Nginx的功能

    • 静态的web资源服务器html,图片,js,css,txt等静态资源
    • http/https协议的反向代理
    • 结合FastCGI/uWSGI/SCGI等协议反向代理动态资源请求
    • tcp/udp协议的请求转发(反向代理)
    • imap4/pop3协议的反向代理
  • Nginx的基础特性

    • 模块化设计,较好的扩展性

    • 高可靠性

    • 支持热部署:不停机更新配置文件,升级版本,更换日志文件

    • 低内存消耗:10000个keep-alive连接模式下的非活动连接,仅需2.5M内存

    • event-driven,aio,mmap,sendfile

1.1.3 Nginx与web服务的相关
  • 虚拟主机(server)
  • 支持 keep-alive 和管道连接(利用一个连接做多次请求)
  • 访问日志(支持基于日志缓冲提高其性能)
  • url rewirte
  • 路径别名
  • 基于IP及用户的访问控制
  • 支持速率限制及并发数限制
  • 重新配置和在线升级而无须中断客户的工作进程

1.2 Nginx 架构和进程

在这里插入图片描述

1.2.1 Nginx 进程结构
  • web请求处理机制

    • 多进程方式:服务器每接收到一个客户端请求就有服务器的主进程生成一个子进程响应客户端,直到用户关闭连接,这样的优势是处理速度快,子进程之间相互独立,但是如果访问过大会导致服务器资源耗尽而无法提供请求
    • 多线程方式:与多进程方式类似,但是每收到一个客户端请求会有服务进程派生出一个线程和此客户端进行交互,一个线程的开销远远小于一个进程,因此多线程方式在很大程度减轻了web服务器对系统资源的要求,但是多线程也有自己的缺点,即当多个线程位于同一个进程内工作的时候,可以相互访问同样的内存地址空间,所以他们相互影响,一旦主进程挂掉则所有子线程都不能工作了,IIS服务器使用了多线程的方式,需要间隔一段时间就重启一次才能稳定。
  • Nginx是多进程组织模型,而且是一个由Master主进程和Worker工作进程组成

在这里插入图片描述

  • 主进程(master process)的功能:

    • 对外接口:接收外部的操作(信号)
    • 对内转发:根据外部的操作的不同,通过信号管理 Worker
    • 监控:监控 worker 进程的运行状态,worker 进程异常终止后,自动重启 worker 进程
    • 读取Nginx 配置文件并验证其有效性和正确性
    • 建立、绑定和关闭socket连接
    • 按照配置生成、管理和结束工作进程
    • 接受外界指令,比如重启、升级及退出服务器等指令
    • 不中断服务,实现平滑升级,重启服务并应用新的配置
    • 开启日志文件,获取文件描述符
    • 不中断服务,实现平滑升级,升级失败进行回滚处理
    • 编译和处理perl脚本
  • 工作进程(worker process)的功能:

    • 所有 Worker 进程都是平等的
    • 实际处理:网络请求,由 Worker 进程处理
    • Worker进程数量:一般设置为核心数,充分利用CPU资源,同时避免进程数量过多,导致进程竞争
    • CPU资源,
    • 增加上下文切换的损耗
    • 接受处理客户的请求
    • 将请求依次送入各个功能模块进行处理
    • I/O调用,获取响应数据
    • 与后端服务器通信,接收后端服务器的处理结果
    • 缓存数据,访问缓存索引,查询和调用缓存数据
    • 发送请求结果,响应客户的请求
    • 接收主程序指令,比如重启、升级和退出等
  • Nginx的进程

在这里插入图片描述

  • Master 工作过程细节:
    1.Master建立listen的socket(listenfd)

    2.Master ,fork 出Worker 进程(fork:进程镜像)

    3.新请求到来时,所有 Worker 进程的 listenfd 都变为可读;

    4.Worker 进程,克accept mutex,狭胜的注册 listenfd 的读事件

    5.Worker 进程,在读事件中,accopt当前连接,并处理请求

  • Worker工作过程细节:
    1.新请求到来时,所有 Worker 进程的 listenfd 都变为可读;

    2.Worker 进程,竞争accept mutex,狭胜的注册 listenfd 的读事件

    3.Worker 进程在读事件中,accept当前连接;

    4.Worker 进程,读取请求、解解析请求、处理请求、进行响应

1.2.2 Nginx进程间的通信

​ 工作进程是由主进程生成的,主进程使用fork()函数,在Nginx服务器启动过程中主进程根据配置文件决定启动工作进程的数量,然后建立一张全局的工作表用于存放当前未退出的所有的工作进程,主进程生成工作进程后会将新生成的工作进程加入到工作进程表中,并建立一个单向的管道并将其传递给工作进程,该管道与普通的管道不同,它是由主进程指向工作进程的单向通道,包含了主进程向工作进程发出的指令、工作进程ID、工作进程在工作进程表中的索引和必要的文件描述符等信息。

​ 主进程与外界通过信号机制进行通信,当接收到需要处理的信号时,它通过管道向相关的工作进程发送正确的指令,每个工作进程都有能力捕获管道中的可读事件,当管道中有可读事件的时候,工作进程就会从管道中读取并解析指令,然后采取相应的执行动作,这样就完成了主进程与工作进程的交互。

  • Nginx的通信过程:

    在这里插入图片描述

  • worker进程之间的通信原理基本上和主进程与worker进程之间的通信是一样的,只要worker进程之间能够取得彼此的信息,建立管道即可通信,但是由于worker进程之间是完全隔离的,因此一个进程想要知道另外一个进程的状态信息,就只能通过主进程来实现。

  • 为了实现worker进程之间的交互,master进程在生成worker进程之后,在worker进程表中进行遍历,将该新进程的PID以及针对该进程建立的管道句柄传递给worker进程中的其他进程,为worker进程之间的通信做准备,当worker进程1向worker进程2发送指令的时候,首先在master进程给它的其他worker进程工作信息中找到2的进程PID,然后将正确的指令写入指向进程2的管道,worker进程2捕获到管道中的事件后,解析指令并进行相关操作,这样就完成了worker进程之间的通信。另worker进程可以通过共享内存来通讯的,比如upstream中的zone,或者limit_req、limit_conn中的zone等。

  • 操作系统提供了共享内存机制

1.2.3 Nginx 启动和HTTP连接建立

在这里插入图片描述

  • Nginx 启动时,Master 进程,加载配置文件
  • Master 进程,初始化监听的 socket
  • Master 进程,fork 出多个 Worker 进程
  • Worker 进程,竞争新的连接,获胜方通过三次握手,建立 Socket 连接,并处理请求
1.2.4 HTTP处理过程

在这里插入图片描述

  • 初始化、准备完成后会逐行读取请求行和请求头

  • 多阶段请求处理过程中:

    • 首次按时location的配置

      1.对应[内容处理]

      2.proxy_pass是context_ hander的一种

      3.反向代理时,proxy_pass一般配置到upstream,upstream也是一种hander

    • Request如果匹配到了虚拟主机(server):

      1.请求地址重写(uri重写为[本地地址])

      2.权限验证(限制ip段访问权限)

      3.生成响应,内容处理:context hander

      4.访问日志

  • 最后过滤数据、数据加工阶段:

    • 过滤response 的hander
    • gzip压缩数据

1.3 Nginx模块介绍

nginx 有多种模块

  • 核心模块:是 Nginx 服务器正常运行必不可少的模块,提供错误日志记录 、配置文件解析 、事件驱动机制 、进程管理等核心功能
  • 标准HTTP模块:提供 HTTP 协议解析相关的功能,比如: 端口配置 、 网页编码设置 、 HTTP响应头设置 等等
  • 可选HTTP模块:主要用于扩展标准的 HTTP 功能,让 Nginx 能处理一些特殊的服务,比如: Flash
  • 多媒体传输 、解析 GeoIP 请求、 网络传输压缩 、 安全协议 SSL 支持等
  • 邮件服务模块:主要用于支持 Nginx 的 邮件服务 ,包括对 POP3 协议、 IMAP 协议和 SMTP协议的支持
  • Stream服务模块: 实现反向代理功能,包括TCP协议代理
  • 第三方模块:是为了扩展 Nginx 服务器应用,完成开发者自定义功能,比如: Json 支持、 Lua 支持等

nginx高度模块化,但其模块早期不支持DSO机制;1.9.11 版本支持动态装载和卸载

模块分类:

核心模块:core module

标准模块:

HTTP 模块: ngx_http_*
	HTTP Core modules  # 默认功能
	HTTP Optional modules # 需编译时指定
Mail 模块: ngx_mail_*
Stream 模块 ngx_stream_*
  • 1
  • 2
  • 3
  • 4
  • 5

第三方模块

在这里插入图片描述

  • ​ 核心模块:
    • ngx_core:核心代码
    • ngx_errorlg:日志
    • ngx_conf:配置文件
    • ngx_regex:正则表达式模块

1.4 Nginx安装

1.4.1 Nginx版本和安装方式
  • Nginx版本

    • Mainline version 主要开发版本,一般为奇数版本号,比如1.19
    • Stable version 当前最新稳定版,一般为偶数版本,如:1.20
    • Legacy versions 旧的稳定版,一般为偶数版本,如:1.18
  • Nginx安装可以使用yum或源码安装,但是推荐使用源码编译安装

    • yum的版本比较旧
    • 编译安装可以更方便自定义相关路径
    • 使用源码编译可以自定义相关功能,更方便业务的上的使用
1.4.2 源码编辑器的安装

编辑器介绍:

源码安装需要提前准备标准的编译器,GCC的全称是(GNU Compiler collection),其有GNU开发,并以GPL即LGPL许可,是自由的类UNIX即苹果电脑Mac OS X操作系统的标准编译器,因为GCC原本只能处理C语言,所以原名为GNU C语言编译器,后来得到快速发展,可以处理C++,Fortran,pascal,objective C,java以及Ada等其他语言,此外还需要Automake工具,以完成自动创建Makefile的工作,Nginx的一些模块需要依赖第三方库,比如: pcre(支持rewrite),zlib(支持gzip模块)和openssl(支持ssl模块)等。

编辑器的安装

[root@nginx ~]# yum install gcc -y
  • 1
1.4.3 Nginx源码编译安装

官方源码包下载地址:https://nginx.org/en/download.html

在这里插入图片描述

在官方中下载源码包,再通过远程软件将其放入到Linux中,也可以复制链接通过wget来进行下载

源码编译安装:

1.# 安装gcc以及Nginx需要的依赖库
[root@nginx ~]# dnf install gcc pcre-devel zlib-devel openssl-devel -y                 # 安装Nginx的依赖库,加入在这一步没有安装相关的依赖库,可以通过编译时的error提示来安装相关的依赖库

2.# 创建nginx用户及用户组
[root@nginx ~]# useradd -s /sbin/nologin -M nginx
[root@nginx ~]# id nginx
用户id=1001(nginx) 组id=1001(nginx)=1001(nginx)

3.# 下载Nginx的源码包
[root@nginx ~]# wget https://nginx.org/download/nginx-1.24.0.tar.gz

4.# 解压编译Nginx
[root@nginx ~]# tar zxf nginx-1.24.0.tar.gz   # 解压nginx源码包
[root@nginx ~]# cd nginx-1.24.0/       # 进入解压目录
[root@nginx nginx-1.24.0]# ls
auto     CHANGES.ru  configure  html     man     src
CHANGES  conf        contrib    LICENSE  README    -- 通过configure环境检测来检测Nginx缺少的依赖库
[root@nginx nginx-1.24.0]# ./configure --help   # 查看configure环境差检测的参数,来定义需要使用的环境参数

[root@nginx nginx-1.24.0]# vim auto/cc/gcc       # 关闭debug功能
# debug
CFLAGS="$CFLAGS -g"   -- 注释关闭debug的调试,使生成的二进制文件更小,在安装时的文件占用空间减小

# 开始编译版本
[root@Nginx nginx-1.24.0]# ./configure --prefix=/usr/local/nginx \  # 通过转义符来继续输入下一个参数
> --user=nginx \ 				 		# 指定nginx运行用户
> --group=nginx \				 		# 指定nginx运行组
> --with-http_ssl_module \ 	 		# 支持https://
> --with-http_v2_module \ 	 		# 支持http版本2
> --with-http_realip_module \ 		# 支持ip透传
> --with-http_stub_status_module \ 	# 支持状态页面
> --with-http_gzip_static_module \ 	# 支持压缩
> --with-pcre \ 						# 支持正则
> --with-stream \ 					# 支持tcp反向代理
> --with-stream_ssl_module \ 			# 支持tcp的ssl加密
> --with-stream_realip_module 		# 支持tcp的透传ip
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

重新查看会发现通过检测后生成Makefile objs这两个文件,通过make调用这两个文件内容来进行编译安装

在这里插入图片描述

若在此过程发现装出现问题可将其还原至原来的解压文件内容

[root@nginx nginx-1.24.0]# make clean
  • 1
[root@Nginx nginx-1.24.0]# make && make install   # 最后通过make完成安装

[root@nginx ~]# du -sh /usr/local/nginx//sbin/nginx     # 关闭debug功能后的软件包大小
1.2M	/usr/local/nginx//sbin/nginx
  • 1
  • 2
  • 3
  • 4

make 负责编译源代码,生成可执行文件。

make install 负责将编译后的文件安装到系统中,使其可用于其他程序或用户。

nginx完成安装以后,有四个主要的目录:

[root@nginx nginx-1.24.0]# ls /usr/local/nginx/
conf  html  logs  sbin
  • 1
  • 2

conf:保存nginx所有的配置文件,其中nginx.conf是nginx服务器的最核心最主要的配置文件,其他的.conf则是用来配置nginx相关的功能的,例如fastcgi功能使用的是fastcgi.conf和fastcgi_params两个文件,配置文件一般都有一个样板配置文件,是以.default为后缀,使用时可将其复制并将default后缀去掉即可。

html:目录中保存了nginx服务器的web文件,但是可以更改为其他目录保存web文件,另外还有一个50x的web文件是默认的错误页面提示页面。

logs:用来保存nginx服务器的访问日志错误日志等日志,logs目录可以放在其他路径,比如/var/logs/nginx里面。

sbin:保存nginx二进制启动脚本,可以接受不同的参数以实现不同的功能。

1.4.4 验证版本及编译参数
[root@nginx ~]# vim ~/.bash_profile         # 把nginx软件的命令执行路径添加到环境变量中
# User specific environment and startup programs
export PATH=$PATH:/usr/local/nginx/sbin 

[root@nginx ~]# source ~/.bash_profile    # 刷新环境变量,应用更改的配置,并立即生效

# 此时可以直接调用nginx命令来执行
例如:
# 查看nginx的版本号
[root@nginx ~]# nginx -v 或 -V
nginx version: nginx/1.24.0
# 或在版本中进行查看
[root@nginx ~]# curl -I 172.25.254.60     # 需要先开启nginx  -- 此IP为本虚拟机IP

# 打开nginx
[root@nginx ~]# nginx

# 关闭nginx
[root@nginx ~]# nginx -s stop

此时不能使用systemctl来查看nginx的状态,但可通过查看进程来确认是否已经启动或关闭
[root@nginx ~]# ps aux | grep nginx
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

测试:

[root@nginx ~]# netstat -antlpue | grep nginx   # 查看nginx的80端口是否已经监听上
[root@nginx nginx-1.24.0]# echo nginx-172.25.254.60 > /usr/local/nginx/html/index.html
[root@nginx nginx-1.24.0]# curl 172.25.254.60
nginx-172.25.254.60
  • 1
  • 2
  • 3
  • 4

注意:一定!!!一定!!!要关闭防火墙以及SeLinux

[root@nginx ~]# systemctl stop firewalld.service 
[root@nginx ~]# systemctl mask firewalld.service 
[root@nginx ~]# setenforce 0
  • 1
  • 2
  • 3
1.4.5 配置Nginx启动文件

注意::在配置Nginx的启动文件前需要将其nginx服务先关闭,否则当配置完文件再启动时会出现端口占用的情况,导致配置文件无法使用,出现error。

[root@nginx ~]# nginx -s stop
  • 1
[root@nginx ~]# vim /lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

[root@nginx ~]# systemctl daemon-reload     # 通知 systemd 重新加载守护进程的配置文件
[root@nginx ~]# systemctl start nginx       # 使用systemctl命令启动nginx服务
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

若在前面忘记关闭nginx的服务,导致在配置启动文件后,不管是通过原来的命令或者是systemctl命令打开/关闭都不会生效,可以通过以下命令来停止

[root@nginx ~]# pkill -f nginx    # 直接关闭nginx
  • 1
1.4.6 隐藏Nginx的版本号

注意:需要在源码编译时进行更改

[root@nginx ~]# vim /root/nginx-1.24.0/src/core/nginx.h
[root@nginx ~]# curl -I 172.25.254.60
HTTP/1.1 200 OK
Server: haha/1.0      # 自定义的名称及版本号
Date: Sat, 17 Aug 2024 14:34:03 GMT
Content-Type: text/html
Content-Length: 20
Last-Modified: Sat, 17 Aug 2024 14:29:08 GMT
Connection: keep-alive
ETag: "66c0b3b4-14"
Accept-Ranges: bytes

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述

1.5 Nginx的命令参数

格式:nginx [参数]

参数作用
-v显示版本和退出
-V显示版本和编译参数
-t测试配置文件是否有误
-T测试并打印
-q静默模式
-s signal发送信号,reload信号会生成新的worker,但master不会重新生成(signal — stop, quit, reopen, reload)
-p prefix指定Nginx目录(default: /etc/nginx/)
-c filename配置文件路径(default: /etc/nginx/nginx.conf)
-g directives设置全局指令,注意和配置文件不要同时配置,否则冲突

命令参数的使用:

1.# nginx -v  --显示版本和退出
[root@nginx ~]# nginx -v
nginx version: nginx/1.24.0

2.# nginx -V  --显示版本和编译参数
[root@nginx ~]# nginx -V
nginx version: nginx/1.24.0
built by gcc 11.3.1 20220421 (Red Hat 11.3.1-2) (GCC) 
built with OpenSSL 3.0.1 14 Dec 2021
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_stub_status_module --with-pcre --with-stream --with-stream_ssl_module --with-http_gzip_static_module --with-stream_realip_module

3. # nginx -t -- 检测nginx的配置文件是否有误
[root@nginx ~]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

4.# nginx -T -- 测试并打印
[root@nginx ~]# nginx -T
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
# configuration file /usr/local/nginx/conf/nginx.conf:
 . . . . . .
 
5.# nginx -s [stop, quit, reopen, reload]
[root@nginx ~]# nginx -s stop  --停止nginx服务
[root@nginx ~]# nginx -s reload  -- 在不关闭nginx的情况下重新加载配置文件

6.# nginx -g "worker_processes 6;"  -- 可指定开启的worker子进程
[root@nginx ~]# vim /usr/local/nginx/conf/nginx.conf    -- 进入nginx的配置文件
#user  nobody;
worker_processes  1;     -- 需要关闭默认指定开启的worker数量,若指定了这个配置参数,不可指定worker子进程数量
[root@nginx ~]# nginx -s stop  -- 先停止nginx服务
[root@nginx ~]# nginx -g "worker_processes 6;"    -- 指定开启多个worker 
[root@nginx ~]# ps aux | grep nginx    -- 查看进程数量
root       47933  0.0  0.0   9836   928 ?        Ss   11:33   0:00 nginx: master process nginx -g worker_processes 6;
nginx      47934  0.0  0.2  13724  4828 ?        S    11:33   0:00 nginx: worker process
nginx      47935  0.0  0.2  13724  4880 ?        S    11:33   0:00 nginx: worker process
nginx      47936  0.0  0.2  13724  4880 ?        S    11:33   0:00 nginx: worker process
nginx      47937  0.0  0.2  13724  4880 ?        S    11:33   0:00 nginx: worker process
nginx      47938  0.0  0.2  13724  4880 ?        S    11:33   0:00 nginx: worker process
nginx      47939  0.0  0.2  13724  4828 ?        S    11:33   0:00 nginx: worker process
root       47941  0.0  0.1 221680  2348 pts/0    S+   11:33   0:00 grep --color=auto nginx

或
[root@Nginx ~]# nginx -g "daemon off;"    # nginx在前台运行
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

1.6 Nginx的平滑升级和版本回滚

有时候我们需要对Nginx版本进行升级以满足对其功能的需求,例如添加新模块,需要新功能,而此时Nginx又在跑着业务无法停掉,这时我们就可能选择平滑升级

1.6.1 平滑升级流程

在这里插入图片描述

  • 将旧Nginx二进制文件换成新Nginx程序文件(注意先备份)
  • 向master进程发送USR2信号
  • master进程修改pid文件名加上后缀.oldbin,成为nginx.pid.oldbin
  • master进程用新Nginx文件启动新master进程成为旧master的子进程,系统中将有新旧两个Nginx主
  • 进程共同提供Web服务,当前新的请求仍然由旧Nginx的worker进程进行处理,将新生成的master进程的PID存放至新生成的pid文件nginx.pid
  • 向旧的Nginx服务进程发送WINCH信号,使旧的Nginx worker进程平滑停止
  • 向旧master进程发送QUIT信号,关闭老master,并删除Nginx.pid.oldbin文件
  • 如果发现升级有问题,可以回滚∶向老master发送HUP,向新master发送QUIT
1.6.2 Nginx的平滑升级和版本回滚案例
1.6.2.1 Nginx的平滑升级

echo-nginx-module 是一个第三方的Nginx模块,由 OpenResty 团队开发,提供了一个灵活的方式来输出文本、变量、子请求结果等内容到客户端响应中。

  • 主要功能:

    • 输出文本或变量:可以输出指定的文本或变量到客户端响应。
    • 支持条件输出:可以根据条件进行选择性输出内容。
    • 嵌套和组合:支持在输出中嵌套其他指令或组合多个输出操作。
    • 子请求支持:可以发起子请求,并将结果输出到客户端响应。
  • 使用场景:

    echo-nginx-module 通常用于需要更复杂的响应逻辑的场景,例如:

    • 动态地返回基于请求信息的内容。
    • 测试和调试,输出某些特定的信息。
    • 处理和调度复杂的响应过程,比如输出来自不同源的数据。

下载支持Nginx的echo模块,在编译时添加新的功能进行编译;

地址:https://github.com/openresty/echo-nginx-module

在这里插入图片描述

下载完成后将其远程传送到Linux虚拟机中,并解压其源码包

[root@nginx ~]# tar zxf echo-nginx-module-0.63.tar.gz   # 解压Nginx的echo模块源码包
  • 1
[root@nginx ~]# wget https://nginx.org/download/nginx-1.26.2.tar.gz  # 下载Nginx目前最新的稳定版本
[root@nginx ~]# tar zxf nginx-1.26.2.tar.gz    # 解压nginx源码包
[root@nginx ~]# cd nginx-1.26.2/               # 进入解压目录

#开始编译新版本
[root@nginx nginx-1.26.2]# ./configure --prefix=/usr/local/nginx \
> --user=nginx \
> --group=nginx \
> --add-module=/root/echo-nginx-module-0.63 \         # 添加新的编译模块
> --with-http_ssl_module \
> --with-http_v2_module \
> --with-http_realip_module \
> --with-http_stub_status_module \
> --with-http_gzip_static_module \
> --with-pcre \
> --with-stream \
> --with-stream_ssl_module \
> --with-stream_realip_module

# 只要make无需要make install
[root@nginx nginx-1.26.2]# make 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
# 查看两个版本
[root@nginx nginx-1.26.2]# ll objs/nginx /usr/local/nginx/sbin/nginx
  • 1
  • 2

在这里插入图片描述

# 把之前的旧版的nginx命令备份
[root@nginx nginx-1.26.2]# cd /usr/local/nginx/sbin/
[root@nginx sbin]# cp nginx nginx.24

# 把新版本的nginx命令复制过去
[root@nginx sbin]# \cp -f /root/nginx-1.26.2/objs/nginx /usr/local/nginx/sbin

# 检测一下有没有问题
[root@nginx sbin]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful

# 平滑升级
[root@nginx ~]# ps aux | grep nginx                    # 查看进程ID
[root@Nginx sbin]# kill -USR2 43645 # nginx master worker ID
#USR2 平滑升级可执行程序,将存储有旧版本主进程PID的文件重命名为nginx.pid.oldbin,并启动新的nginx
#此时两个master的进程都在运行,只是旧的master不在监听,由新的master监听80
#此时Nginx开启一个新的master进程,这个master进程会生成新的worker进程,这就是升级后的Nginx进程,此时老的进程不会自动退出,但是当接收到新的请求不作处理而是交给新的进程处理。

# 再查看进程
[root@nginx ~]# ps aux | grep nginx
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

在这里插入图片描述

# 查看此时的版本
[root@nginx sbin]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.24.0         -- 依旧是旧版生效
Date: Sat, 17 Aug 2024 14:59:17 GMT
Content-Type: text/html
Content-Length: 20
Last-Modified: Sat, 17 Aug 2024 14:29:08 GMT
Connection: keep-alive
ETag: "66c0b3b4-14"
Accept-Ranges: bytes

# 也可以使用循环测试来检测在切换版本时naginx是否会掉线
[root@nginx ~]# while true
> do
> curl 172.25.254.60 ; sleep 1
> done
nginx-172.25.254.60
nginx-172.25.254.60
nginx-172.25.254.60
. . . . . . 

# 回收旧版本
[root@nginx sbin]# kill -WINCH 43645    -- 回收旧msater的进程ID
[root@nginx sbin]# ps aux | grep nginx
root       43645  0.0  0.1   9836  2596 ?        Ss   22:30   0:00 nginx: master process /usr/local/nginx/sbin/nginx
root       46999  0.0  0.3   9872  6076 ?        S    22:36   0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx      47000  0.0  0.2  13760  4720 ?        S    22:36   0:00 nginx: worker process
root       47064  0.0  0.1 221812  2340 pts/0    S+   23:30   0:00 grep --color=auto nginx

# 检测版本信息
[root@nginx sbin]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.26.2             -- 回收完旧版本后切换到新版本
Date: Sat, 17 Aug 2024 15:30:28 GMT
Content-Type: text/html
Content-Length: 20
Last-Modified: Sat, 17 Aug 2024 14:29:08 GMT
Connection: keep-alive
ETag: "66c0b3b4-14"
Accept-Ranges: bytes
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
1.6.2.2 Nginx的版本回滚

如果升级的版本发现问题需要回滚,可以重新拉起旧版本的worker

# 回滚
[root@nginx sbin]# cp nginx nginx.26   # 将1.26版本的nginx进行备份
[root@nginx sbin]# ls
nginx  nginx.24  nginx.26

# 重新启用1.24版本的nginx
[root@nginx sbin]# mv nginx.24 nginx
mv:是否覆盖'nginx'yes

# 优雅重新加载nginx的配置文件,而不需要停止进程
[root@nginx sbin]# kill -HUP 43645      -- HUP旧master进程
[root@nginx sbin]# ps aux | grep nginx
root       43645  0.0  0.1   9836  2596 ?        Ss   22:30   0:00 nginx: master process /usr/local/nginx/sbin/nginx
root       46999  0.0  0.3   9872  6076 ?        S    22:36   0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx      47000  0.0  0.2  13760  4720 ?        S    22:36   0:00 nginx: worker process
nginx      47076  0.0  0.2  13724  4796 ?        S    23:38   0:00 nginx: worker process
root       47078  0.0  0.1 221812  2296 pts/0    S+   23:38   0:00 grep  --color=auto nginx

# 回收1.26版本的master进程ID
[root@nginx sbin]# ps aux | grep nginx
root       43645  0.0  0.1   9836  2596 ?        Ss   22:30   0:00 nginx: master process /usr/local/nginx/sbin/nginx
root       46999  0.0  0.3   9872  6076 ?        S    22:36   0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx      47076  0.0  0.2  13724  4796 ?        S    23:38   0:00 nginx: worker process
root       47081  0.0  0.1 221812  2332 pts/0    S+   23:40   0:00 grep --color=auto nginx
[root@nginx sbin]# kill -9 46999
[root@nginx sbin]# ps aux | grep nginx   # 再次查看发现1.26版本的进程已经被关掉

# 查看nginx版本
[root@nginx sbin]# curl -I localhost
HTTP/1.1 200 OK
Server: nginx/1.24.0          # 版本回滚完成
Date: Sat, 17 Aug 2024 15:40:53 GMT
Content-Type: text/html
Content-Length: 20
Last-Modified: Sat, 17 Aug 2024 14:29:08 GMT
Connection: keep-alive
ETag: "66c0b3b4-14"
Accept-Ranges: bytes
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/1016136
推荐阅读
相关标签
  

闽ICP备14008679号