Linux编译安装nginx并平滑升级和回滚

Posted 白-胖-子

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux编译安装nginx并平滑升级和回滚相关的知识,希望对你有一定的参考价值。

编译安装nginx

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并平滑升级和回滚的主要内容,如果未能解决你的问题,请参考以下文章

web服务之nginx命令,信号还有平滑升级与回滚

lamp架构nginx并发优化平滑升级与回滚

lamp架构nginx并发优化平滑升级与回滚

lamp架构nginx并发优化平滑升级与回滚

Linux----------nginx平滑升级

[Linux]-Nginx平滑升级