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

news2024/11/25 11:01:59

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_*

第三方模块

在这里插入图片描述

  • ​ 核心模块:
    • 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.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

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

在这里插入图片描述

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

[root@nginx nginx-1.24.0]# make clean
[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

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

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

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

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

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

测试:

[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

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

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

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

[root@nginx ~]# nginx -s stop
[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服务

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

[root@nginx ~]# pkill -f nginx    # 直接关闭nginx
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.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.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模块源码包
[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 
# 查看两个版本
[root@nginx nginx-1.26.2]# ll objs/nginx /usr/local/nginx/sbin/nginx

在这里插入图片描述

# 把之前的旧版的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

在这里插入图片描述

# 查看此时的版本
[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.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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2061452.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何用CWE API 来减轻软件产品中的安全风险

本文分享自华为云开发者社区《用CWE API 减轻软件产品中的安全风险》作者: Uncle_Tom 1. CWE REST API 推出的目的 8 月 8 号,CWE™ 计划推出了“CWE REST API”。 CWE™计划由美国网络安全与基础设施安全局(Cybersecurity & Infrastructure Secur…

PyTorch——Dataloader使用

一、Dataloader是啥 前面我在写PyTorch的第一篇文章里讲过Dataset是啥,Dataset就是将数据集分类,并且分析出这些数据集它的位置哪、大小多少、这个数据集一共有多少数据......等等信息 那么把Dataset比作一副扑克牌,那么如果你就让这副牌放在…

《机器学习》 逻辑回归 大批量数据的下采样 <8>

一、案例文件 同样使用上节课的银行贷款案例,其文件内容大致如下:(共28万多条,31列) 现在要继续接着上节课的内容对模型进行优化 二、下采样流程 1、流程图示 2、具体流程介绍 1)切分原数据集 大…

77、ansible及常见模块

ansible 一、ansible: 远程自动化运维 ansible是基于python开发的配置管理和应用部署工具。 也是自动化运维的重要工具。 可以批量配置,部署,管理上千台主机。 只需要在一台主机ansible就可以完成其他主机的操作。 1.1、操作模式&…

Dell 服务器 PowerEdge T440 通过BIOS配置RAID阵列

目录 1.清除当前RAID磁盘阵列配置 1.1开机按F2进入System Setup管理界面; 1.2点击Device Settings; 1.3选择RAID controller in Slot 4:DELL PERC Configuration Utility;卡型号> 1.4选择Configuration Management; 1.5选择View Dis…

Java 2.4 - JVM

一、Java 内存区域详解(重点) 本篇讨论的是 HotSpot 虚拟机 相比于 C 而言,程序员不需要对每个 new 操作都写对应的 delete / free 操作,这些操作我们会交给虚拟机去做。因此,如果不了解虚拟机的原理,一旦…

React 学习——React.memo

1、默认情况下:子跟着父一起渲染 2、memo 缓存,只有props发生变化的时候才会重新渲染 import { memo, useState } from react; // 默认情况下:子跟着父一起渲染 //memo 缓存,只有props发生变化的时候才会重新渲染 const MemoSon memo(function Son()…

Java使用Easy Excel对Excel进行操作

Easy Excel使用教程API&#xff1a; 读Excel | Easy Excel 官网 使用代码示例&#xff1a; 需要自行创建一个Maven项目&#xff0c;然后pom文件中需要的依赖如下&#xff1a; <dependencies><!-- easyExcel 表格依赖 --><dependency><groupId>com.a…

Qt实现tcp协议

void Widget::readyRead_slot() {//读取服务器发来的数据QByteArray msg socket->readAll();QString str QString::fromLocal8Bit(msg);QStringList list str.split(:);if(list.at(0) userName){QString str2;for (int i 1; i < list.count(); i) {str2 list.at(i);…

数据结构初阶(1)——算法的时间复杂度和空间复杂度

目录 1.算法效率 1.1 如何衡量一个算法的好坏 1.2算法的复杂度 2.时间复杂度 2.1时间复杂度的概念 2.2大O的渐进表示法 2.3常见时间复杂度计算举例 4. 常见复杂度对比 5.复杂度的oj练习 5.1消失的数字 5.2旋转数组 1.算法效率 1.1 如何衡量一个算法的好坏 代码不一…

探索数据结构:并查集的分析与实现

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;数据结构与算法 贝蒂的主页&#xff1a;Betty’s blog 1. 并查集的引入 1.1 并查集的概念 并查集是一种树型数据结构&#xf…

StarRocks 存算分离数据回收原理

前言 StarRocks存算分离表中&#xff0c;垃圾回收是为了删除那些无用的历史版本数据&#xff0c;从而节约存储空间。考虑到对象存储按照存储容量收费&#xff0c;因此&#xff0c;节约存储空间对于降本增效尤为必要。 在系统运行过程中&#xff0c;有以下几种情况可能会需要删…

详解华为项目管理,附华为高级项目管理内训材料

&#xff08;一&#xff09;华为在项目管理中通过有效的沟通、灵活的组织结构、坚持不懈的努力、细致的管理和科学的考核体系&#xff0c;实现了持续的创新和发展。通过引进先进的管理模式&#xff0c;强调以客户需求为导向&#xff0c;华为不仅优化了技术管理和项目研发流程&a…

el-table自定义样式,表头固定,数据过多时滚动

最终效果&#xff1a;&#xff08;此处没体现出来滚动&#xff0c;数据没那么多&#xff09; 1.表头固定&#xff0c;设置表头样式&#xff0c;修改表格背景色 <div class"category-table"> <el-table ref"tableRef" class"common-table&quo…

java之类和对象的介绍

1.面向对象和面向过程的概念&#xff1a; 面向对象&#xff1a;面向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事。 面向过程&#xff1a;注重完成一件事情的过程&#xff0c;后续代码维护扩展较为麻烦。 以洗衣服为例&#xff0c;面向对象为传统…

微软AI人工智能认证有哪些?

微软提供的人工智能认证主要包括以下几个方面&#xff1a; Azure AI Fundamentals&#xff08;AI900认证&#xff09;&#xff1a;这是一个基础认证&#xff0c;旨在展示与Microsoft Azure软件和服务开发相关的基本AI概念&#xff0c;以创建AI解决方案。它面向具有技术和非技术…

C++学习路线分享

我上大学学的第一门编程语言便是C&#xff0c;靠着那本饱受诟病的谭浩强版的教材度过了大一上学期。学的内容现在看来相当之浅&#xff0c;如果没记错的话只学了个基本的语法&#xff0c;考试的时候考一些冒泡&#xff0c;快排之类的东西就结束了。感觉那些有计算机教育背景的学…

解决Qt多线程中fromRawData函数生成的QByteArray数据不一致问题

解决Qt多线程中fromRawData函数生成的QByteArray数据不一致问题 目录 &#x1f514; 问题背景&#x1f4c4; 问题代码❓ 问题描述&#x1fa7a; 问题分析✔ 解决方案 &#x1f514; 问题背景 在开发一个使用Qt框架的多线程应用程序时&#xff0c;我们遇到了一个棘手的问题&…

【Linux】生产消费模型实践 --- 基于信号量的环形队列

你送出去的每颗糖都去了该去的地方&#xff0c; 其实地球是圆的&#xff0c; 你做的好事终会回到你身上。 --- 何炅 --- 基于信号量的环形队列 1 信号量2 框架构建3 代码实现4 测试运行 1 信号量 信号量本质是一个计数器&#xff0c;可以在初始化时对设置资源数量&#xf…

数据结构——链式队列和循环队列

目录 引言 队列的定义 队列的分类 1.单链表实现 2.数组实现 队列的功能 队列的声明 1.链式队列 2.循环队列 队列的功能实现 1.队列初始化 (1)链式队列 (2)循环队列 (3)复杂度分析 2.判断队列是否为空 (1)链式队列 (2)循环队列 (3)复杂度分析 3.判断队列是否…