Nginx平滑升级,nginx的平滑升级

Nginx平滑升级目录 一. 为什么要对 nginx 平滑升级
二. Nginx 平滑升级原理
三. 前提准备
四. 安装一个模拟被升级旧Nginx版本
五. 模拟真实业务场景
六. 下载获取一个扩展模块
七. 模拟升级Ngin

目录

1. 为什么需要nginx平滑升级

2.Nginx平滑升级原则

3. 前置准备

4.安装模拟升级到较旧的Nginx版本

5. 模拟真实业务场景

6.下载并获取扩展模块

7. 模拟Nginx升级

一. 为什么要对 nginx 平滑升级

随着nginx越来越流行,nginx的好处越来越明显,nginx的版本迭代也进入了加速模式。 nginx 1.9.0版本更新了许多新功能,包括streams 4。层代理功能随着nginx的普及,版本升级必然会变得更快,线上业务无法停止。

nginx 对于平滑升级很有用。这个原理的简单总结如下。 (1) 开始一个新的进程而不停止旧的进程。 (2)旧进程负责处理尚未处理的请求,但将不再接受处理请求。 (3)新进程接受新请求。 (4)处理完所有请求并关闭所有连接后,停止旧进程。 这有利于平滑升级。一般来说,需要升级nginx有两种情况。一是实际升级nginx的版本,二是给nginx添加新的模块。

二. Nginx 平滑升级原理

多进程模式下如何分配请求

Nginx 默认以多进程模式运行。即master进程启动后,完成加载配置、端口绑定等动作,并fork出指定数量的worker进程,这些子进程保存文件。指定监听端口(fd),并在描述符中添加监听事件以接受连接(accept)。

信号接收与处理

nginx主进程一旦启动,就处于等待状态,负责响应SIGCHLD、SIGHUP、SIGUSR2等各种系统消息。

Nginx 信号概述

主进程支持的信号

TERM,INT: 立即终止

QUIT: 等待工作进程完成后再退出

KILL: 终止进程

HUP: 重新加载配置文件,使用新配置启动工作进程,并逐渐关闭旧进程。

USR1: 重新打开日志文件

USR2:启动新的主进程,实现热升级。

WINCH: 逐渐关闭工作进程

工作进程支持的信号

TERM,INT: 立即终止

QUIT: 请等待请求处理完后再退出

USR1: 重新打开日志文件

三. 前提准备

准备初始化的虚拟机

本地主机Rocky_linux9.4192.168.226.20

关闭防火墙和SElinux

在继续基本虚拟机配置脚本之前,首先运行该脚本。

#!/bin/bash

#**************************************************** * ******

# * 文件名: Rocky_linux

# * 作者: 驼鹿

# * 电子邮件: zzdict@gmail.com/elk_deer@foxmail.com

# * 创建时间: 2024-06-15 20:12

# * 描述:

#**************************************************** * ******

# 检查脚本是否以root 用户身份运行

if [ \’$(id -u)\’ -ne 0 ];

大胆

输入设置1

tput setaf 3

echo \’请以root 用户身份运行此脚本。 \’

输入sgr0

1号出口

# 启用网络接口

启用网络接口(){

本地接口=$1

如果ip链接设置“$interface”。

大胆

tput setaf 2

echo \’网络接口$interface已启用。 \’

输入sgr0

除此之外

大胆

输入设置1

echo \’无法启用网络接口$interface。请检查接口名称。 \’

输入sgr0

1号出口

}

# 设置YUM 源

配置yum_repos() {

sed -e \’s|^mirrorlist=|#mirrorlist=|g\’ \\

-e \’s|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g\’ \\

-i.bak \\

/etc/yum.repos.d/Rocky-*.repo

大胆

tput setaf 2

echo \’YUM 源配置已更新。 \’

输入sgr0

dnf 制作缓存

yum -y 安装epel-release

}

# 停止并禁用防火墙并禁用SELinux

配置安全(){

systemctl 停止防火墙。 systemctl 禁用防火墙。

防火墙-cmd –重新加载

大胆

tput setaf 2

echo \’防火墙已停止并禁用。 \’

输入sgr0

sed -i \’s/SELINUX=enforcing/SELINUX=disabled/\’ /etc/selinux/config

大胆

tput setaf 2

echo \’SELinux 已禁用。 \’

输入sgr0

}

# 检查并安装chrony时间同步

函数install_and_sync_time_with_chrony() {

# 检查是否安装了chrony

if 命令-v chronyd /dev/null;

sudo dnf install -y chrony /dev/null

# 检查是否安装成功

if 命令-v chronyd /dev/null;

大胆

输入设置1

echo \’慢性安装失败。请检查您的包管理器并重试。 \’

输入sgr0

1号出口

除此之外

大胆

tput setaf 2

echo \’chrony 安装成功。 \’

输入sgr0

除此之外

大胆

tput setaf 2

echo \’Crony 已安装。 \’

输入sgr0

# 确保安装了其他必需的包

sudo dnf install -y vim wget 解压tar lrzsz /dev/null

如果[ $? -eq 0 ];

大胆

tput setaf 2

echo \’其他软件包安装成功。 \’

输入sgr0

除此之外

大胆

输入设置1

echo \’安装其他包失败。 \’

输入sgr0

1号出口

}

# 启动chronyd 服务并启用启动功能

当sudo systemctl 启动chronyd 时当sudo systemctl 启用chronyd 时。

大胆

tput setaf 2

echo \’chronyd 服务已成功启动并设置为在启动时启动。 \’

输入sgr0

除此之外

大胆

输入设置1

echo \’chronyd 服务启动或启用失败。检查systemctl的状态。 \’

输入sgr0

1号出口

# 强制同步时间

sudo chronyc – 执行步骤

大胆

tput setaf 2

echo \’时间同步成功完成。 \’

输入sgr0

}

# 自定义IP地址

配置IP 地址(){

大胆

输入设置1

read -p \’****请输入你要设置的IP : \’ ip_a

输入sgr0

大胆

tput setaf 6

read -p \’****请输入您要配置的网关:\’ gat

输入sgr0

大胆

tput setaf 3

read -p \’*****请输入您要配置的DNS :\’ dnns

输入sgr0

# 查看当前连接的名称

connection_name=$(nmcli -t -f NAME,DEVICE con show –active | grep -E \’ens33|有线连接1\’ | Cut -d: -f1)

if [[ \’$connection_name\’==\’ens33\’ ]];

# ens33 连接设置

nmcli con mod \’ens33\’ ipv4.method 手动ipv4.addresses \’${ip_a}/24\’ ipv4.gateway \’${gat}\’ ipv4.dns \’${dnns}\’ 自动连接是

elif [[ \’$connection_name\’==\’有线连接1\’ ]];

# 设置有线连接1连接

nmcli con mod \’有线连接1\’ ipv4.method 手动ipv4.addresses \’${ip_a}/24\’ ipv4.gateway \’${gat}\’ ipv4.dns \’${dnns}\’ 自动连接是

除此之外

大胆

输入设置1

echo \’无法识别的网络连接名称:$connection_name\’

输入sgr0

返回1

tput设置5

tput 设置15

大胆

echo \’IP地址已配置成功,系统即将重启。 \’

输入sgr0

nmcli 启动\’$connection_name\’

重启

}

主功能

主要的() {

本地接口=\’ens33\’

启用_网络_接口\’$接口\’

配置yum_repos

配置安全

install_and_sync_time_with_chrony

配置IP 地址\’$ 接口\’

}

# 调用主函数

主要的

访问官网下载两个不同版本

官网:nginx:下载

下载两个不同的版本进行实验,并从较低版本升级到较高版本。

将下载的两个安装包上传到虚拟机中,如下图。

[root@localhost ~]# ll

总计2268

-rw——.1根根815 6月6日14:00 anaconda-ks.cfg

-rw-r–r– 1 root root 1062124 六月22 00:38 nginx-1.20.2.tar.gz

-rw-r–r– 1 root root 1244738 六月21 21:19 nginx-1.26.1.tar.gz

-rw-r–r– 1 root root 4251 六月17 23:50 Rocky_linux.sh

四. 安装一个模拟被升级旧Nginx版本

1.安装依赖工具

[root@localhost ~]# yum install -y gcc gcc-c++ pcre-devel openssl-devel zlib-devel

2.解压1.20.2版本安装包。

[root@localhost ~]# ls

anaconda-ks.cfg nginx-1.20.2.tar.gz nginx-1.26.1.tar.gz rocky_linux.sh

[root@localhost ~]# tar -zxf nginx-1.20.2.tar.gz

3.切换到解压后的目录

[root@localhost ~]# ls

anaconda-ks.cfg nginx-1.20.2 nginx-1.20.2.tar.gz nginx-1.26.1.tar.gz rocky_linux.sh

[root@localhost ~]# cd nginx-1.20.2

[root@localhost nginx-1.20.2]# ls

更改CHANGES.ru 许可证自述文件auto conf 配置contrib html man src

4. 预编译

这里有两个模块没有写入代码。用于用少量模块模拟此类场景,方便后续升级和扩展。

[root@localhost nginx-1.20.2]# ./configure –prefix=/usr/local/nginx –group=nginx –user=nginx –sbin-path=/usr/local/nginx/sbin/nginx –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –http-log-path=/var/log/nginx/access.log –http-client-body-temp-path=/tmp/nginx/client_body –http-proxy-temp-path=/tmp/nginx/proxy –http-fastcgi-temp-path=/tmp/nginx/fastcgi –pid-path=/var/run/nginx.pid –lock-path=/var/lock/nginx –with-http_stub_status_module –with-http_ssl_module –with-http_gzip_static_module –with-pcre –with- http_realip_模块

5.编译安装

[root@localhost nginx-1.20.2]# make make install

6.创建nginx系统用户

[root@localhost nginx-1.20.2]# useradd –system –no-create-home –shell /sbin/nologin nginx

7、创建目录,临时存放客户端请求数据和缓存文件。

[root@localhost nginx-1.20.2]# mkdir -p /tmp/nginx/client_body

8.启动nginx

[root@localhost nginx-1.20.2]# /usr/local/nginx/sbin/nginx

9.验证nginx是否正常工作

[root@localhost nginx-1.20.2]#curl -Ik 192.168.226.20

HTTP/1.1 200 好

服务器: nginx/1.20.2

日期: 2024 年6 月22 日星期六05:16:03 GMT

内容类型: 文本/html

内容长度: 612

最后修改时间: 2024 年6 月22 日星期六01:00:47 GMT

连接:保持活动

ETag:\’6676223f-264\’

接受范围: 字节

或者,打开浏览器并更改主机的IP 地址。

五. 模拟真实业务场景

使用go代码不断向某个主机地址发送请求,模拟用户访问,模拟真实的业务场景。

监视升级过程中是否发生故障,或者是否存在任何中断性访问。当然,少量的失败是可以接受的。

包主

进口(

“FMMT”

“艾欧”

“网络/http”

\’时间\’

//ANSI颜色代码

持续的(

红色=\’\\033[31m\’

绿色=\’\\033[32m\’

黄色=\’\\033[33m\’

重置颜色=\’\\033[0m\’

//记录成功、失败、无响应和服务暂时不可用(503)请求的数量。

var successCount int 变量

varfailureCount int 变量

var 无响应计数int

var tempUnavailableCount int //503 添加一个新变量来跟踪服务不可用状态的请求数量

//makeRequest 向指定的URL 发送GET 请求,并根据响应是否成功以不同颜色打印响应状态和经过的时间。

func makeRequest(url 字符串, 尝试int) {

开始时间:=时间.Now()

响应,错误:=http.Get(url)

经过的时间:=time.since(startTime)

如果出现错误!=nil {

//如果由于网络或服务器问题导致请求失败,则视为“未响应”。

fmt.Printf(\'[%d] %s请求未响应: %s %.4f 秒%s\\n\’, 已尝试, RedColor, 错误, elapsedTime.Seconds(), ResetColor)

无回复计数++

返回

}

defer func(Body io.ReadCloser) {

错误:=Body.Close()

如果出现错误!=nil {

fmt.Printf(\’关闭响应正文时出错: %s\\n\’, err)

}

}(每个身体)

颜色:=绿色

如果resp.StatusCode==503 {

颜色=黄色

tempUnavailableCount++ //返回503 状态代码的请求计数。

否则如果resp.StatusCode !=200 {

颜色=红色

失败次数++

} 除此之外{

成功次数++

}

//根据状态码,以对应颜色输出响应状态码和持续时间

fmt.Printf(\'[%d] %s%d %.4f 秒%s\\n\’, Trial, color, resp.StatusCode, elapsedTime.Seconds(), ResetColor)

}

函数主() {

url :=\’http://192.168.226.20\’ //选择要测试的地址

totalAttempts :=20000 //自定义请求次数

开始时间:=时间.Now()

尝试:=1; 尝试=总尝试++ {

makeRequest(URL, 尝试)

time.Sleep(1 * time.Second) //每个请求之间等待1 秒

}

总运行时间:=time.since(startTime)

成功率:=(float64(成功计数)/float64(总尝试次数)) * 100

失败率:=(float64(failureCount)/float64(totalAttempts)) * 100

un 响应速度:=(float64(un 响应次数)/float64(总尝试次数)) * 100

tempUnavailableRate :=(float64(tempUnavailableCount)/float64(totalAttempts)) * 100 //计算503个状态码的比率

fmt.Printf(\’%s总运行时间: %.4f 秒%s\\n\’, ResetColor,totalElapsedTime.Seconds(), ResetColor)

fmt.Printf(\’成功率: %.2f%%,失败率: %.2f%%,无响应请求率: %.2f%%,服务暂时不可用请求率(503) : %.2f%% \\n\’ 、成功率、失败率、未知率、tempUnavailableRate)

}

如图所示:

六. 下载获取一个扩展模块

1.下载扩展模块

[root@localhost ~]# cd

[root@localhost ~]# wget https://github.com/zls0424/ngx_req_status/archive/master.zip -O ngx_req_status

.zip

2. 解压并查看

[root@localhost ~]# unzip ngx_req_status.zip
Archive: ngx_req_status.zip
428ffbb511fcb456218b4d2e6fb2f6f3e5abcf08
creating: ngx_req_status-master/
inflating: ngx_req_status-master/README
inflating: ngx_req_status-master/README.md
inflating: ngx_req_status-master/config
inflating: ngx_req_status-master/module_patch.sh
inflating: ngx_req_status-master/ngx_http_req_status_module.c
inflating: ngx_req_status-master/write_filter-1.7.11.patch
inflating: ngx_req_status-master/write_filter.patch
[root@localhost ~]# ll
total 2280
-rw——-. 1 root root 815 Jun 6 14:00 anaconda-ks.cfg
drwxr-xr-x 9 1001 1001 186 Jun 22 00:58 nginx-1.20.2
-rw-r–r– 1 root root 1062124 Jun 22 00:38 nginx-1.20.2.tar.gz
drwxr-xr-x 8 502 games 158 May 29 22:30 nginx-1.26.1
-rw-r–r– 1 root root 1244738 Jun 21 21:19 nginx-1.26.1.tar.gz
drwxr-xr-x 2 root root 169 Oct 21 2015 ngx_req_status-master
-rw-r–r– 1 root root 11237 Jun 22 13:50 ngx_req_status.zip
-rw-r–r– 1 root root 4251 Jun 17 23:50 rocky_linux.sh

3.解压升级的nginx版本压缩包

[root@localhost ~]# cd
[root@localhost ~]# tar -zxf nginx-1.26.1.tar.gz
4.将该模块拷贝到升级的nginx版本解压后的目录里

[root@localhost ~]# cp -r ngx_req_status-master/ nginx-1.26.1/

5.安装一些依赖包,并确保都已安装

[root@localhost ~]# yum -y install pcre pcre-devel openssl openssl-devel gcc gcc-c++ zlib zlib-devel
[root@localhost ~]# yum -y install patch.x86_64

七. 模拟升级Nginx 

1.进入升级的nginx版本目录里,可以看到刚拷贝进来的扩展模块也在

[root@localhost ~]# cd nginx-1.26.1/
[root@localhost nginx-1.26.1]# ll
total 828
-rw-r–r– 1 502 games 327587 May 29 22:30 CHANGES
-rw-r–r– 1 502 games 501144 May 29 22:30 CHANGES.ru
-rw-r–r– 1 502 games 1397 May 28 21:28 LICENSE
-rw-r–r– 1 502 games 49 May 28 21:28 README
drwxr-xr-x 6 502 games 4096 Jun 22 13:29 auto
drwxr-xr-x 2 502 games 168 Jun 22 13:29 conf
-rwxr-xr-x 1 502 games 2611 May 28 21:28 configure
drwxr-xr-x 4 502 games 72 Jun 22 13:29 contrib
drwxr-xr-x 2 502 games 40 Jun 22 13:29 html
drwxr-xr-x 2 502 games 21 Jun 22 13:29 man
drwxr-xr-x 2 root root 169 Jun 22 13:58 ngx_req_status-master
drwxr-xr-x 9 502 games 91 May 29 22:30 src

2.应用相应的补丁

[root@localhost nginx-1.26.1]# patch -p1 < ./ngx_req_status-master/write_filter-1.7.11.patch
3.预编译

和上面那个预编译的步骤相比,多加了两个模块 

[root@localhost nginx-1.26.1]# ./configure –prefix=/usr/local/nginx –group=nginx –user=nginx –sbin-path=/usr/local/nginx/sbin/nginx –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –http-log-path=/var/log/nginx/access.log –http-client-body-temp-path=/tmp/nginx/client_body –http-proxy-temp-path=/tmp/nginx/proxy –http-fastcgi-temp-path=/tmp/nginx/fastcgi –pid-path=/var/run/nginx.pid –lock-path=/var/lock/nginx –with-http_stub_status_module –with-http_ssl_module –with-http_gzip_static_module –with-pcre –with-http_realip_module –with-stream –with-http_image_filter_module –add-module=./ngx_req_status-master
 4.编译

[root@localhost nginx-1.26.1]# make
升级不要再执行make install

5.备份旧版本nginx

[root@localhost nginx]# cd /usr/local/nginx/sbin
[root@localhost sbin]# mv nginx nginx.bak
[root@localhost sbin]# ll
total 4268
-rwxr-xr-x 1 root root 4368512 Jun 22 09:00 nginx.bak

 6.拷贝新版本的nginx到当前目录

[root@localhost sbin]# cp /root/nginx-1.26.1/objs/nginx ./
[root@localhost sbin]# ll
total 9336
-rwxr-xr-x 1 root root 5186960 Jun 22 14:20 nginx
-rwxr-xr-x 1 root root 4368512 Jun 22 09:00 nginx.bak

7.测试新版本的nginx是否正常

[root@localhost sbin]# ./nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

 8.给nginx发送平滑迁移信号(若不清楚pid路径,请查看nginx配置文件)

[root@localhost sbin]# kill -USR2 `cat /var/run/nginx.pid`
9.查看nginx pid,会出现一个nginx.pid.oldbin

[root@localhost sbin]# ll /var/run/nginx.pid*
-rw-r–r– 1 root root 5 Jun 22 14:25 /var/run/nginx.pid
-rw-r–r– 1 root root 5 Jun 22 13:14 /var/run/nginx.pid.oldbin
10.查看当前nginx进程

会有两组nginx进程,一组是前面旧版本的13:14分运行的,一组是刚刚14:24运行的,即新起来的进程

[root@localhost sbin]# ps aux |grep nginx
root 1435 0.0 0.1 9556 2528 ? Ss 13:14 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 1436 0.0 0.2 13948 5088 ? S 13:14 0:03 nginx: worker process
root 6202 0.0 0.3 9684 6528 ? S 14:24 0:00 nginx: master process /usr/local/nginx/sbin/nginx
nginx 6203 0.0 0.2 13980 5100 ? S 14:24 0:00 nginx: worker process
root 6207 0.0 0.1 3876 1920 pts/0 S+ 14:26 0:00 grep –color=auto nginx

11.从容关闭旧的Nginx进程

此时旧版本的worker进程会关闭

[root@localhost sbin]# kill -WINCH `cat /var/run/nginx.pid.oldbin`
注意声明:

不重载配置启动旧的工作进程,该步骤是在如果新进程察觉到有问题,回滚启用旧nginx进程。如果没有问题,此步骤不操作。

kill -HUP `cat /var/run/nginx.pid.oldbin`

12.结束工作进程,完成此次升级

[root@localhost sbin]# kill -QUIT `cat /var/run/nginx.pid.oldbin`
 13.验证Nginx是否升级成功

[root@localhost sbin]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.26.1
built by gcc 11.4.1 20231218 (Red Hat 11.4.1-3) (GCC)
built with OpenSSL 3.0.7 1 Nov 2022
TLS SNI support enabled
configure arguments: –prefix=/usr/local/nginx –group=nginx –user=nginx –sbin-path=/usr/local/nginx/sbin/nginx –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –http-log-path=/var/log/nginx/access.log –http-client-body-temp-path=/tmp/nginx/client_body –http-proxy-temp-path=/tmp/nginx/proxy –http-fastcgi-temp-path=/tmp/nginx/fastcgi –pid-path=/var/run/nginx.pid –lock-path=/var/lock/nginx –with-http_stub_status_module –with-http_ssl_module –with-http_gzip_static_module –with-pcre –with-http_realip_module –with-stream –add-module=./ngx_req_status-master

[root@localhost sbin]# curl -Ik 192.168.226.20
HTTP/1.1 200 OK
Server: nginx/1.26.1
Date: Sat, 22 Jun 2024 06:38:12 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Sat, 22 Jun 2024 01:00:47 GMT
Connection: keep-alive
ETag: \”6676223f-264\”
Accept-Ranges: bytes

旧版本的nginx需要观察一段时间,确定不会影响业务需求再进行删除。 
#以上关于Nginx平滑升级的相关内容来源网络仅供参考,相关信息请以官方公告为准!

原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/91623.html

(0)
CSDN's avatarCSDN
上一篇 2024年6月22日 下午8:31
下一篇 2024年6月22日 下午9:07

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注