Linux编译安装nginx并平滑升级和回滚
Posted 白-胖-子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux编译安装nginx并平滑升级和回滚相关的知识,希望对你有一定的参考价值。
编译安装nginx
- 编译安装可以方便的自定义功能模块
- 编译安装可以方便的自定义程序部署路径
- 编译安装可以方便的自定义内核
- CentOS 8 编译安装nginx:https://blog.csdn.net/timonium/article/details/117690956
nginx 命令和信号
- nginx即是服务也是程序
nginx命令
- nginx 命令支持向其发送信号,实现不同功能
nginx 命令格式
nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
ngxin 命令选项说明
- 帮助: -? -h
- 使用指定的配置文件: -c
- 指定配置指令:-g
- 指定运行目录:-p
- 测试配置文件是否有语法错误:-t -T
- 打印nginx的版本信息、编译信息等:-v -V
- 发送信号: -s 示例: nginx -s reload
nginx 信号选项说明
nginx -s signal : send signal to a master process: stop, quit, reopen, reload
- 立刻停止服务:stop,相当于信号SIGTERM,SIGINT
- 优雅的停止服务:quit,相当于信号SIGQUIT
- 平滑重启,重新加载配置文件: reload,相当于信号SIGHUP
- 重新开始记录日志文件:reopen,相当于信号SIGUSR1,在切割日志时用途较大
- 平滑升级可执行程序:发送信号SIGUSR2,在升级版本时使用
- 优雅的停止工作进程:发送信号SIGWINCH,在升级版本时使用
nginx平滑升级
- 当需要对Nginx进行版本升级或者添加新模块,增加新功能时,
- 为避免Nginx停服造成业务损失,需要对nginx不停服平滑升级
nginx平滑升级主要流程
- 将旧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
平滑升级nginx 1.18.0至nginx1.20.1
检查服务器当前nginx版本和编译参数以及服务状态
- nginx版本和编译参数
nginx -V
- nginx服务状态
systemctl status nginx.service
[root@C8-189 ~]# nginx -V
nginx version: nginx/1.18.0
built by gcc 8.4.1 20200928 (Red Hat 8.4.1-1) (GCC)
built with OpenSSL 1.1.1g FIPS 21 Apr 2020
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --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
[root@C8-189 ~]# systemctl status nginx.service
● nginx.service - The nginx HTTP and reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since Tue 2021-06-15 18:28:44 CST; 9min ago
Process: 33534 ExecStart=/apps/nginx/sbin/nginx (code=exited, status=0/SUCCESS)
Process: 33532 ExecStartPre=/apps/nginx/sbin/nginx -t (code=exited, status=0/SUCCESS)
Process: 33530 ExecStartPre=/bin/rm -f /apps/nginx/logs/nginx.pid (code=exited, status=0/SUC>
Main PID: 33535 (nginx)
Tasks: 2 (limit: 11353)
Memory: 2.4M
CGroup: /system.slice/nginx.service
├─33535 nginx: master process /apps/nginx/sbin/nginx
└─33536 nginx: worker process
Jun 15 18:28:44 C8-189 systemd[1]: Starting The nginx HTTP and reverse proxy server...
Jun 15 18:28:44 C8-189 nginx[33532]: nginx: the configuration file /apps/nginx/conf/nginx.conf>
Jun 15 18:28:44 C8-189 nginx[33532]: nginx: configuration file /apps/nginx/conf/nginx.conf tes>
Jun 15 18:28:44 C8-189 systemd[1]: Started The nginx HTTP and reverse proxy server.
获取最新稳定版ngxin 1.20.1
下载最新ngxin 1.20.1源码包
[ -a nginx-1.20.1 ] || wget -cP /usr/local/src/ http://nginx.org/download/nginx-1.20.1.tar.gz
[root@C8-189 ~]# [ -a nginx-1.20.1 ] || wget -cP /usr/local/src/ http://nginx.org/download/nginx-1.20.1.tar.gz
--2021-06-15 18:48:28-- http://nginx.org/download/nginx-1.20.1.tar.gz
Resolving nginx.org (nginx.org)... 3.125.197.172, 52.58.199.22, 2a05:d014:edb:5702::6, ...
Connecting to nginx.org (nginx.org)|3.125.197.172|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1061461 (1.0M) [application/octet-stream]
Saving to: ‘/usr/local/src/nginx-1.20.1.tar.gz’
nginx-1.20.1.tar.gz 100%[========================================================>] 1.01M 10.5KB/s in 1m 57s
2021-06-15 18:50:26 (8.87 KB/s) - ‘/usr/local/src/nginx-1.20.1.tar.gz’ saved [1061461/1061461]
解压源码包
cd /usr/local/src/ && tar xf nginx-1.20.1.tar.gz
[root@C8-189 src]# ll nginx-1.20.1
total 788
drwxr-xr-x 6 1001 1001 326 Jun 15 18:52 auto
-rw-r--r-- 1 1001 1001 311503 May 25 20:35 CHANGES
-rw-r--r-- 1 1001 1001 475396 May 25 20:35 CHANGES.ru
drwxr-xr-x 2 1001 1001 168 Jun 15 18:52 conf
-rwxr-xr-x 1 1001 1001 2590 May 25 20:35 configure
drwxr-xr-x 4 1001 1001 72 Jun 15 18:52 contrib
drwxr-xr-x 2 1001 1001 40 Jun 15 18:52 html
-rw-r--r-- 1 1001 1001 1397 May 25 20:35 LICENSE
drwxr-xr-x 2 1001 1001 21 Jun 15 18:52 man
-rw-r--r-- 1 1001 1001 49 May 25 20:35 README
drwxr-xr-x 9 1001 1001 91 Jun 15 18:52 src
使用当前nginx程序编译选项重新编译新版本ngxin
cd /usr/local/src/nginx-1.20.1 && nginx -V 2>&1 | awk -F: '/^configure/ {print $2}' | xargs ./configure
make 开始进行源代码编译
make && objs/nginx -v
……
-ldl -lpthread -lcrypt -lpcre -lssl -lcrypto -ldl -lpthread -lz \\
-Wl,-E
sed -e "s|%%PREFIX%%|/apps/nginx|" \\
-e "s|%%PID_PATH%%|/apps/nginx/logs/nginx.pid|" \\
-e "s|%%CONF_PATH%%|/apps/nginx/conf/nginx.conf|" \\
-e "s|%%ERROR_LOG_PATH%%|/apps/nginx/logs/error.log|" \\
< man/nginx.8 > objs/nginx.8
make[1]: Leaving directory '/usr/local/src/nginx-1.20.1'
nginx version: nginx/1.20.1
备份原nginx主程序文件
mv /apps/nginx/sbin/nginx{,.bak}
[root@C8-189 nginx-1.20.1]# which nginx
/usr/local/bin/nginx
[root@C8-189 nginx-1.20.1]# ll /usr/local/bin/ngxin
ls: cannot access '/usr/local/bin/ngxin': No such file or directory
[root@C8-189 nginx-1.20.1]# ll /usr/local/bin/nginx
lrwxrwxrwx 1 root root 22 Jun 15 18:02 /usr/local/bin/nginx -> /apps/nginx/sbin/nginx
[root@C8-189 nginx-1.20.1]# mv /apps/nginx/sbin/nginx{,.bak}
[root@C8-189 nginx-1.20.1]# ll /apps/nginx/sbin/
total 7416
-rwxr-xr-x 1 root root 7591152 Jun 15 18:02 nginx.bak
将新编译过的ngxin主程序文件复制过去
cp objs/nginx /apps/nginx/sbin/
[root@C8-189 nginx-1.20.1]# cp objs/nginx /apps/nginx/sbin/
[root@C8-189 nginx-1.20.1]# ll /apps/nginx/sbin/
total 14960
-rwxr-xr-x 1 root root 7723320 Jun 15 20:13 nginx
-rwxr-xr-x 1 root root 7591152 Jun 15 18:02 nginx.bak
检查新nginx主程序和配置文件是否有语法不兼容问题
/apps/nginx/sbin/nginx -t
[root@C8-189 nginx-1.20.1]# /apps/nginx/sbin/nginx -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
[root@C8-189 nginx-1.20.1]# /apps/nginx/sbin/nginx.bak -t
nginx: the configuration file /apps/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /apps/nginx/conf/nginx.conf test is successful
发送-USR2信号给正在运行的nginx主进程
- USR2 信号平滑升级可执行程序,将存储有旧版本主进程PID的文件重命名为nginx.pid.oldbin,并启动新的nginx
- 发送信号后,此时两个master的进程都在运行,只是旧的master不在监听,由新的master监听80
- 接收到信号后,Nginx开启一个新的master进程,这个master进程会生成新的worker进程,这就是升级后的Nginx进程,
- 原有主进程不会自动退出,但是当接收到新的请求不作处理而是交给新的进程处理。
cat $(find / -name nginx.pid) | xargs kill -USR2
[root@C8-189 ~]# ps aux | grep nginx
root 33535 0.0 0.0 41064 848 ? Ss 18:28 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 33536 0.0 0.2 74580 4648 ? S 18:28 0:00 nginx: worker process
root 36728 0.0 0.0 12112 1100 pts/0 S+ 20:20 0:00 grep --color=auto nginx
[root@C8-189 ~]# find / -name nginx.pid
/apps/nginx/logs/nginx.pid
[root@C8-189 ~]# cat /apps/nginx/logs/nginx.pid
33535
[root@C8-189 ~]# kill -USR2 33535
[root@C8-189 ~]# ps auxf | grep nginx
root 36759 0.0 0.0 12112 1068 pts/0 S+ 20:23 0:00 \\_ grep --color=auto nginx
root 33535 0.0 0.1 41064 2688 ? Ss 18:28 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 33536 0.0 0.2 74580 4648 ? S 18:28 0:00 \\_ nginx: worker process
root 36756 0.0 0.3 41088 5772 ? S 20:22 0:00 \\_ nginx: master process /apps/nginx/sbin/nginx
nginx 36757 0.0 0.2 74692 5136 ? S 20:22 0:00 \\_ nginx: worker process
发送 -winch信号给原nginx主进程
- 先关闭旧nginx的worker进程,而不关闭nginx主进程方便回滚
- 向原Nginx主进程发送WINCH信号,它会逐步关闭旗下的工作进程(主进程不退出),
- 此时所有请求都会由新版Nginx处理
- 如果旧版worker进程有用户的请求,会一直等待处理完后才会关闭
cat $(find / -name nginx.pid.oldbin) | xargs kill -winch
[root@C8-189 ~]# cat $(find / -name nginx.pid.oldbin) | xargs echo
33535
[root@C8-189 ~]# cat $(find / -name nginx.pid.oldbin) | xargs kill -winch
[root@C8-189 ~]# ps auxf | grep nginx
root 36785 0.0 0.0 12112 1056 pts/0 S+ 20:33 0:00 \\_ grep --color=auto nginx
root 33535 0.0 0.1 41064 2688 ? Ss 18:28 0:00 nginx: master process /apps/nginx/sbin/nginx
root 36756 0.0 0.3 41088 5772 ? S 20:22 0:00 \\_ nginx: master process /apps/nginx/sbin/nginx
nginx 36757 0.0 0.2 74692 5136 ? S 20:22 0:00 \\_ nginx: worker process
发送 -quit信号给原nginx主程序
- 新程序运行一段时间确定没问题后
- 发送-quit信号优雅的退出原nginx主程序
cat $(find / -name nginx.pid.oldbin) | xargs kill -quit
[root@C8-189 ~]# cat $(find / -name nginx.pid.oldbin) | xargs kill -quit
[root@C8-189 ~]# ps auxf | grep nginx
root 36792 0.0 0.0 12112 1084 pts/0 S+ 20:37 0:00 \\_ grep --color=auto nginx
root 36756 0.0 0.3 41088 5772 ? S 20:22 0:00 nginx: master process /apps/nginx/sbin/nginx
nginx 36757 0.0 0.2 74692 5136 ? S 20:22 0:00 \\_ nginx: worker process
查看nginx版本,升级完成
- 至此,优雅的平滑升级nginx1.18.0至1.20.1完成!
[root@C8-189 ~]# nginx -V
nginx version: nginx/1.20.1
built by gcc 8.4.1 20200928 (Red Hat 8.4.1-1) (GCC)
built with OpenSSL 1.1.1g FIPS 21 Apr 2020
TLS SNI support enabled
configure arguments: --prefix=/apps/nginx --user=nginx --group=nginx --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
[root@C8-189 ~]# curl -I 127.0.0.1
HTTP/1.1 200 OK
Server: nginx/1.20.1
Date: Tue, 15 Jun 2021 13:04:28 GMT
Content-Type: text/html
Content-Length: 648
Last-Modified: Tue, 15 Jun 2021 10:02:43 GMT
Connection: keep-alive
ETag: "60c87ac3-288"
Accept-Ranges: bytes
nginx平滑升级后回滚
- 需要在原主程序未退出前执行回滚操作
- 如果升级的版本发现问题需要回滚,可以重新拉起旧版本的worker
发送-hup信号给原主程序pid文件
- 原主程序pid文件被更名至nginx.pid.oldbin
- 通过发送kill信号唤醒原主程序进程
cat $(find / -name nginx.pid.oldbin) | xargs kill -hup
以上是关于Linux编译安装nginx并平滑升级和回滚的主要内容,如果未能解决你的问题,请参考以下文章