rpm包安装的nginx热升级

一、本地环境基本介绍

本次测试环境,是通过nginx早期提供的yum仓库安装的nginx。所以准确来说,算是官方提供的rpm包来安装的,安装文件目录层级结构:

[root@node1 nginx]# rpm -ql nginx
/etc/logrotate.d/nginx
/etc/nginx
/etc/nginx/conf.d
/etc/nginx/conf.d/default.conf
/etc/nginx/fastcgi_params
/etc/nginx/koi-utf
/etc/nginx/koi-win
/etc/nginx/mime.types
/etc/nginx/modules
/etc/nginx/nginx.conf
/etc/nginx/scgi_params
/etc/nginx/uwsgi_params
/etc/nginx/win-utf
/etc/sysconfig/nginx
/etc/sysconfig/nginx-debug
/usr/lib/systemd/system/nginx-debug.service
/usr/lib/systemd/system/nginx.service
/usr/lib64/nginx
/usr/lib64/nginx/modules
/usr/libexec/initscripts/legacy-actions/nginx
/usr/libexec/initscripts/legacy-actions/nginx/check-reload
/usr/libexec/initscripts/legacy-actions/nginx/upgrade
/usr/sbin/nginx
/usr/sbin/nginx-debug
/usr/share/doc/nginx-1.14.0
/usr/share/doc/nginx-1.14.0/COPYRIGHT
/usr/share/man/man8/nginx.8.gz
/usr/share/nginx
/usr/share/nginx/html
/usr/share/nginx/html/50x.html
/usr/share/nginx/html/index.html
/var/cache/nginx
/var/log/nginx

[root@node1 nginx]# rpm -qa|grep nginx
nginx-1.14.0-1.el7_4.ngx.x86_64

二、yum升级命令说明

(1) 检测nginx是否有可用更新包

[root@node1 ~]# yum check nginx
Loaded plugins: fastestmirror
check ['nginx']
[root@node1 ~]# yum check-update
[root@node1 ~]# yum check-update nginx
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: centos.ustc.edu.cn
 * epel: mirrors.aliyun.com
 * extras: mirrors.shu.edu.cn
 * updates: mirrors.shu.edu.cn

nginx.x86_64                                                  1:1.14.1-1.el7_4.ngx                                                  nginx
[root@node1 ~]# 

[root@node1 ~]# yum list updates nginx
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: centos.ustc.edu.cn
 * epel: mirrors.aliyun.com
 * extras: mirrors.shu.edu.cn
 * updates: mirrors.shu.edu.cn
Updated Packages
nginx.x86_64                                                                                                   1:1.14.1-1.el7_4.ngx                                                                                                    nginx
[root@node1 ~]# 

(2) 如何通过yum更新nginx

#检测到有可用更新后,并且做过调查,就可以尝试更新(生产环境不建议用最新),可以参考epel源最新版本
yum update nginx

三、升级好nginx后如何不中断业务切换

官网关于nginx信号控制说明:http://nginx.org/en/docs/control.html

3.1、nginx相关的信号说明

nginx的管理进程(master process)可以接受指定的几种系统信号:

  1. SIGINT, SIGTERM
    Shut down quickly.
    快速关闭;
  2. SIGHUP
    Reload configuration, start the new worker process with a new configuration, and gracefully shut down old worker processes.
    重载配置,新启动的工作进程是重读配置后的,然后旧的工作进程会平滑关闭,等待其处理完旧的连接会话后;
  3. SIGQUIT
    Shut down gracefully.
    平滑的关闭;
  4. SIGUSR1
    Reopen log files.
    重新打开日志文件;
  5. SIGUSR2
    Upgrade the nginx executable on the fly.
    在线升级nginx执行程序文件;
  6. SIGWINCH
    Shut down worker processes gracefully.
    平滑关闭工作进程;

实际使用:
上边是系统信号名称,如果用配合nginx使用,使用形式为kill -SIGNAL `cat /path/to/pidfile`
可用SIGNAL有:

(1) TERM, INT
fast shutdown.
快速关闭,不安全退出,强杀;
对应于系统信号:
SIGINT, SIGTERM
等价于kill -9,非特殊情况不建议使用;

(2) QUIT
graceful shutdown。
平滑关闭。
对应于系统信号:SIGQUIT
已经建立连接的请求会处理完毕后退出;

(3) HUP	
changing configuration, keeping up with a changed time zone (only for FreeBSD and Linux), starting new worker processes with a new configuration, graceful shutdown of old worker processes。
重载配置;
对应于系统信号:SIGHUP

(4) USR1
re-opening log files
重读日志文件。
对应于系统信号:SIGUSR1

(5) USR2	
upgrading an executable file。
升级可执行文件。
对应于系统信号:SIGUSR2

(6) WINCH
graceful shutdown of worker processes
平滑关闭nginx工作进程。
对应于系统信号:SIGWINCH

nginx的工作进程(worker process)可以接受指定的几种系统信号:

  1. SIGTERM
    Shut down quickly.
    快速关闭;
  2. SIGQUIT
    Shut down gracefully.
    平滑关闭;
  3. SIGUSR1
    Reopen log files.
    重新打开日志文件;

实际使用:
上边是系统信号名称,如果用配合nginx使用,使用形式为kill -SIGNAL worker_pid
可用SIGNAL有(实际不需要手动对工作进程操作,因为工作进程是由管理进程来管理的):


(1) TERM, INT	
fast shutdown
快速关闭。
先找到工作进程的pid,然后kill -TERM pid或kill -INT pid,这个是强制退出;

(2) QUIT
graceful shutdown
平滑关闭,操作方式同TERM或INT。

(3) USR1	
re-opening log files
重新打开日志文件。

(4) WINCH	
abnormal termination for debugging (requires debug_points to be enabled)
调试异常终止(需要启用debug_points)

nginx二进制程序可以通过-s 选项传递给nginx对应的参数,表示给nginx管理进程发送对应的信号。标准形式:

-s signal
其中signal可以为stop,quit,reopen,reload;

stop:SIGTERM(快速关闭);
quit:SIGQUIT(平滑关闭);
reopen:SIGUSR1(重新打开日志文件);
reload:SIGHUP(重载配置,新启动的工作进程是重读配置后的,然后旧的工作进程会平滑关闭,等待其处理完旧的连接会话后);

3.2、在线热升级nginx可执行文件程序

  • 理论说明
    (1) 用新的nginx二进制程序文件替换旧的二进制程序文件;替换前建议先备份旧的二进制文件。
    替换的方式,如果是源码包编译安装,可以直接cp替换或者其他方式替换。如果是rpm包或者yum直接更新升级,建议先用cp等工具备份一下旧的二进制程序文件;
    (2) 向nginx的管理进程发送USR2信号
    管理进程会把旧的pid文件备份成类似于nginx.pid.oldbin的形式。然后启用一个新的管理进程,并且创建了对应的pid文件,新的管理进程会去启动新的工作进程。此时,应该存在新旧两个管理进程以及新旧管理进程启动的工作进程,新旧工作进程此时会继续接收处理请求;
    (3) 向旧的管理进程发送WINCH信号
    旧的管理进程会向旧的工作进程发送消息,请求平滑关闭它们,然后旧的工作进程将不再接受新的请求,如果正在处理旧的请求的要等处理完成后自动关闭,没有在处理的旧的工作进程会直接退出。
    (4) 过一段时间后,通过工具确认没有旧的工作进程在处理请求后,只剩下新旧管理进程和新的工作进程。
    默认,旧的管理进程不会关闭它监听的套接字,如果后续有需要,它可以重新再管理他自己的工作进程,以便回滚处理连接请求。如果刚好由于某些原因,升级二进制程序不成功,要回滚的。
    比如因为一些原因,新的执行文件不工作,要按照以下步骤回滚:
    a) 向旧的管理进程发送HUB信号
    信号接收后,旧的工作进程将会重新开启工作进程(不会重读加载配置)。此时,旧的工作进程开始工作后,要向之前新的管理进程发送QUIT信号,以便之前新的管理进程通过它之前管理的工作进程,让它们平滑关闭。
    b) 发送TERM信号给新的工作进程。
    它会向它的工作进程发送消息让它们立即退出,它们受到消息后会立即离开。如果进程由于某些原因不理解退出,KILL信号将会发送给它们迫使他们去退出。一旦新的工作管理进程退出后,旧的管理进程将会自动开启新的工作进程。
    新的工作进程退出后,旧的工作进程会被nginx.pid.oldbin后缀给去掉。

如果升级成功,应该发送QUIT信号给旧的管理进程。

  • 实际操作
    (1) 备份nginx二进制程序文件
[root@node1 ~]# mv /usr/sbin/nginx{,.bak}
[root@node1 ~]# ls -l /usr/sbin/nginx
ls: cannot access /usr/sbin/nginx: No such file or directory
[root@node1 ~]# ls -l /usr/sbin/nginx.bak 
-rwxr-xr-x 1 root root 1307560 Apr 17  2018 /usr/sbin/nginx.bak
[root@node1 ~]# ps uax|grep nginx
root       2113  0.0  0.3  46428  1724 ?        Ss   16:22   0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx      2183  0.0  0.3  46828  1860 ?        S    16:36   0:00 nginx: worker process
nginx      2184  0.0  0.3  46828  1856 ?        S    16:36   0:00 nginx: worker process
root       2584  0.0  0.1 112640   960 pts/2    S+   17:44   0:00 grep --color=auto nginx
#这里不用担心由于二进制程备份导致处理连接连接请求失败,因为nginx的进程已经启动,二进制程序已经
读取到内存中去了。
#如果/usr/sbin/nginx-debug有用,最好也备份一下。

(2) yum升级nginx

[root@node1 ~]# yum update nginx
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: centos.ustc.edu.cn
 * epel: mirrors.aliyun.com
 * extras: mirrors.shu.edu.cn
 * updates: mirrors.shu.edu.cn
Resolving Dependencies
--> Running transaction check
---> Package nginx.x86_64 1:1.14.0-1.el7_4.ngx will be updated
---> Package nginx.x86_64 1:1.14.1-1.el7_4.ngx will be an update
--> Finished Dependency Resolution

Dependencies Resolved

============================================================================================================================================================================================================================================
 Package                                              Arch                                                  Version                                                              Repository                                            Size
============================================================================================================================================================================================================================================
Updating:
 nginx                                                x86_64                                                1:1.14.1-1.el7_4.ngx                                                 nginx                                                753 k

Transaction Summary
============================================================================================================================================================================================================================================
Upgrade  1 Package

Total download size: 753 k
Is this ok [y/d/N]: y
Downloading packages:
No Presto metadata available for nginx
nginx-1.14.1-1.el7_4.ngx.x86_64.rpm                                                                                                                                                                                  | 753 kB  00:00:24     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  Updating   : 1:nginx-1.14.1-1.el7_4.ngx.x86_64                                                                                                                                                                                        1/2 
  Cleanup    : 1:nginx-1.14.0-1.el7_4.ngx.x86_64                                                                                                                                                                                        2/2 
  Verifying  : 1:nginx-1.14.1-1.el7_4.ngx.x86_64                                                                                                                                                                                        1/2 
  Verifying  : 1:nginx-1.14.0-1.el7_4.ngx.x86_64                                                                                                                                                                                        2/2 

Updated:
  nginx.x86_64 1:1.14.1-1.el7_4.ngx                                                                                                                                                                                                         

Complete!

此时nginx二进制程序为新的二进制程序了。

[root@node1 ~]# which nginx
/usr/sbin/nginx
[root@node1 ~]# ls -l /usr/sbin/nginx
-rwxr-xr-x 1 root root 1307696 Nov  6 22:04 /usr/sbin/nginx
[root@node1 ~]# /usr/sbin/nginx -v
nginx version: nginx/1.14.1

(3) 向nginx的管理进程发送USR2信号

[root@node1 ~]# ls -l /var/run/nginx.pid 
-rw-r--r-- 1 root root 5 Nov 19 17:46 /var/run/nginx.pid
[root@node1 ~]# ps axw -o pid,ppid,user,%cpu,vsz,wchan,command | egrep '(nginx|PID)'
   PID   PPID USER     %CPU    VSZ WCHAN  COMMAND
  2656      1 root      0.0  46304 sigsus nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
  2658   2656 nginx     0.0  46708 ep_pol nginx: worker process
  2659   2656 nginx     0.0  46708 sleep_ nginx: worker process
  2685   2201 root      0.0 107888 inotif tailf /var/log/nginx/access.log
  2695   2387 root      0.0 112644 pipe_w grep -E --color=auto (nginx|PID)
[root@node1 ~]# cat /var/run/nginx.pid 
2656
[root@node1 ~]# kill -USR2 `cat /var/run/nginx.pid`
[root@node1 ~]# ps axw -o pid,ppid,user,%cpu,vsz,wchan,command | egrep '(nginx|PID)'
   PID   PPID USER     %CPU    VSZ WCHAN  COMMAND
  2656      1 root      0.0  46304 sigsus nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
  2658   2656 nginx     0.0  46708 ep_pol nginx: worker process
  2659   2656 nginx     0.0  46708 ep_pol nginx: worker process
  2685   2201 root      0.0 107888 inotif tailf /var/log/nginx/access.log
  2698   2656 root      0.0  46304 sigsus nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
  2699   2698 nginx     0.0  46708 ep_pol nginx: worker process
  2700   2698 nginx     0.0  46708 ep_pol nginx: worker process
  2702   2387 root      0.0 112644 -      grep -E --color=auto (nginx|PID)
[root@node1 ~]# ls -l /var/run/nginx.pid*
-rw-r--r-- 1 root root 5 Nov 19 17:53 /var/run/nginx.pid
-rw-r--r-- 1 root root 5 Nov 19 17:46 /var/run/nginx.pid.oldbin
[root@node1 ~]# cat /var/run/nginx.pid 
2698
[root@node1 ~]# cat /var/run/nginx.pid.oldbin 
2656

(4) 测试发信升级后,可以接受新的连接后。向旧的管理进程发送WINCH信号

#新连接请求,我就不截图了,大概看一下业务没有问题。能接受新请求,就可以开始下一步
[root@node1 ~]# kill -WINCH `cat /var/run/nginx.pid.oldbin`
[root@node1 ~]# ps axw -o pid,ppid,user,%cpu,vsz,wchan,command | egrep '(nginx|PID)'
   PID   PPID USER     %CPU    VSZ WCHAN  COMMAND
  2656      1 root      0.0  46304 sigsus nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
  2685   2201 root      0.0 107888 inotif tailf /var/log/nginx/access.log
  2698   2656 root      0.0  46304 sigsus nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
  2699   2698 nginx     0.0  46708 ep_pol nginx: worker process
  2700   2698 nginx     0.0  46708 ep_pol nginx: worker process
  2719   2387 root      0.0 112644 pipe_w grep -E --color=auto (nginx|PID)

(5) 确认旧的工作进程没有都平滑退出后,可以看看升级是否成功。如果可以,直接向旧的
管理进程发送QUIT信号

[root@node1 ~]# ps axw -o pid,ppid,user,%cpu,vsz,wchan,command | egrep '(nginx|PID)'
   PID   PPID USER     %CPU    VSZ WCHAN  COMMAND
  2656      1 root      0.0  46304 sigsus nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
  2698   2656 root      0.0  46304 sigsus nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
  2699   2698 nginx     0.0  46708 ep_pol nginx: worker process
  2700   2698 nginx     0.0  46708 ep_pol nginx: worker process
  2724   2387 root      0.0 112644 pipe_w grep -E --color=auto (nginx|PID)
  #上边已经没有旧的工作进程在处理旧的请求了
 [root@node1 ~]# kill -QUIT `cat /var/run/nginx.pid.oldbin`
[root@node1 ~]# ps axw -o pid,ppid,user,%cpu,vsz,wchan,command | egrep '(nginx|PID)'
   PID   PPID USER     %CPU    VSZ WCHAN  COMMAND
  2698      1 root      0.0  46304 sigsus nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
  2699   2698 nginx     0.0  46708 ep_pol nginx: worker process
  2700   2698 nginx     0.0  46708 ep_pol nginx: worker process
  2733   2387 root      0.0 112644 pipe_w grep -E --color=auto (nginx|PID)
[root@node1 ~]# ls -l /var/run/nginx.pid 
-rw-r--r-- 1 root root 5 Nov 19 17:53 /var/run/nginx.pid
[root@node1 ~]# ls -l /var/run/nginx.pid*
-rw-r--r-- 1 root root 5 Nov 19 17:53 /var/run/nginx.pid
#为了确认无误,可以重载一下配置:
[root@node1 ~]# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
[root@node1 ~]# nginx -s reload
[root@node1 ~]# ps axw -o pid,ppid,user,%cpu,vsz,wchan,command | egrep '(nginx|PID)'
   PID   PPID USER     %CPU    VSZ WCHAN  COMMAND
  2698      1 root      0.0  46436 sigsus nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
  2738   2698 nginx     0.0  46840 ep_pol nginx: worker process
  2739   2698 nginx     0.0  46840 ep_pol nginx: worker process
  2741   2387 root      0.0 112644 pipe_w grep -E --color=auto (nginx|PID)

申明:本测试是基于测试环境完成,如果有需要做类似的操作,生产环境操作请慎重。因为nginx的可执行程序热升级,可能会导致其他问题(鉴于学术有限,这里没法列出)。

猜你喜欢

转载自blog.csdn.net/u012271055/article/details/84257574