所谓的热升级也叫做热部署,或者平滑升级,也就是说,在不停止nginx服务的情况下,完成nginx的升级工作
但是这里有一个注意点,就是使用这种方法有一个前提,前提就是你在启动nginx时使用的是nginx二进制文件的绝对路径,而不是直接在命令行中输入"nginx"的方式启动的nginx服务,不通过绝对路径启动的方式通常是为了方便,配置了nginx相关的环境变量,如果没有通过绝对路径启动nginx,那么当你向nginx进程发送更新的信号时,nginx进程可能会无法找到新的二进制程序(由于没有找新版本的二进制程序,所以没有任何反应)
准备
这假设已经编译好了新版本的nginx的二进制文件。如下:
cd ~/nginx-1.14.2/objs/
ls -l nginx
-rwxr-xr-x. 1 root root 5789128 4月 3 16:12 nginx
备份旧nginx
cp /var/nginx/sbin/nginx /var/nginx/sbin/nginx.old
覆盖旧nginx
cp -r ~/nginx-1.14.2/objs/nginx /var/nginx/sbin/nginx
对比一下新旧nginx二进制文件:
cd /var/nginx/sbin/
ls -l
总用量 11256
-rwxr-xr-x. 1 root root 5789128 4月 3 16:26 nginx
-rwxr-xr-x. 1 root root 5730664 4月 3 16:20 nginx.old
启用新nginx的master进程
查看旧的nginx进程情况:
ps -ef | grep nginx
nginx 9412 1 0 15:12 ? 00:00:00 nginx: master process /var/nginx/sbin/nginx -c /var/nginx/conf/nginx.conf
nginx 15551 9412 0 16:52 ? 00:00:00 nginx: worker process
nginx 15552 9412 0 16:52 ? 00:00:00 nginx: worker process
nginx 15553 9412 0 16:52 ? 00:00:00 nginx: worker process
nginx 15554 9412 0 16:52 ? 00:00:00 nginx: worker process
root 15556 9963 0 16:52 pts/1 00:00:00 grep --color=auto nginx
向旧nginx的master进程发送USR2信号,加载新的nginx二进制文件,启动新的nginx的master进程:
kill -USR2 9412
ps -ef | grep nginx
nginx 9412 1 0 15:12 ? 00:00:00 nginx: master process /var/nginx/sbin/nginx -c /var/nginx/conf/nginx.conf
nginx 15551 9412 0 16:52 ? 00:00:00 nginx: worker process
nginx 15552 9412 0 16:52 ? 00:00:00 nginx: worker process
nginx 15553 9412 0 16:52 ? 00:00:00 nginx: worker process
nginx 15554 9412 0 16:52 ? 00:00:00 nginx: worker process
nginx 15574 9412 0 16:54 ? 00:00:00 nginx: master process /var/nginx/sbin/nginx -c /var/nginx/conf/nginx.conf
nginx 15575 15574 0 16:54 ? 00:00:00 nginx: worker process
nginx 15576 15574 0 16:54 ? 00:00:00 nginx: worker process
nginx 15577 15574 0 16:54 ? 00:00:00 nginx: worker process
nginx 15578 15574 0 16:54 ? 00:00:00 nginx: worker process
root 15580 9963 0 16:54 pts/1 00:00:00 grep --color=auto nginx
可以看到新起来的master进程是属于旧的master进程的子进程的,并且新旧的work进程都起来了。
关闭旧nginx的work进程
新的master进程起来的同时,新的work进程也启动了,这里需要优雅的退出旧work进程,即向旧的master进程发送WINCH信号退出旧的work进程:
kill -WINCH 9412
ps -ef | grep nginx
nginx 9412 1 0 15:12 ? 00:00:00 nginx: master process /var/nginx/sbin/nginx -c /var/nginx/conf/nginx.conf
nginx 15574 9412 0 16:54 ? 00:00:00 nginx: master process /var/nginx/sbin/nginx -c /var/nginx/conf/nginx.conf
nginx 15575 15574 0 16:54 ? 00:00:00 nginx: worker process
nginx 15576 15574 0 16:54 ? 00:00:00 nginx: worker process
nginx 15577 15574 0 16:54 ? 00:00:00 nginx: worker process
nginx 15578 15574 0 16:54 ? 00:00:00 nginx: worker process
root 15608 9963 0 16:57 pts/1 00:00:00 grep --color=auto nginx
到这里新的work进程就已经完全替换了旧的work进程。
收尾工作
完成上面的工作,其实,新的nginx已经在正常的工作了,如果运行一段时间,出现因为nginx升级导致的错误,就需要进行回滚操作;或者,运行一段时间,没有问题,nginx旧的master进程就可以彻底退出了。
回滚——还原旧nginx的work进程
回滚方式1
# 查看进程状况
ps -ef | grep nginx
nginx 9412 1 0 15:12 ? 00:00:00 nginx: master process /var/nginx/sbin/nginx -c /var/nginx/conf/nginx.conf
nginx 15574 9412 0 16:54 ? 00:00:00 nginx: master process /var/nginx/sbin/nginx -c /var/nginx/conf/nginx.conf
nginx 15575 15574 0 16:54 ? 00:00:00 nginx: worker process
nginx 15576 15574 0 16:54 ? 00:00:00 nginx: worker process
nginx 15577 15574 0 16:54 ? 00:00:00 nginx: worker process
nginx 15578 15574 0 16:54 ? 00:00:00 nginx: worker process
root 15685 9963 0 17:01 pts/1 00:00:00 grep --color=auto nginx
# 发送USR1信号给旧的master进程,准备回滚
kill -USR1 9412
# 发送QUIT信号给新的master进程,彻底退出新的master进程
kill -QUIT 15574
# 查看进程状况
ps -ef | grep nginx
nginx 9412 1 0 15:12 ? 00:00:00 nginx: master process /var/nginx/sbin/nginx -c /var/nginx/conf/nginx.conf
nginx 15686 9412 0 17:01 ? 00:00:00 nginx: worker process
nginx 15687 9412 0 17:01 ? 00:00:00 nginx: worker process
nginx 15688 9412 0 17:01 ? 00:00:00 nginx: worker process
nginx 15689 9412 0 17:01 ? 00:00:00 nginx: worker process
root 15691 9963 0 17:01 pts/1 00:00:00 grep --color=auto nginx
回滚方式2
# 查看进程状况
ps -ef | grep nginx
nginx 9412 1 0 15:12 ? 00:00:00 nginx: master process /var/nginx/sbin/nginx -c /var/nginx/conf/nginx.conf
nginx 15720 9412 0 17:04 ? 00:00:00 nginx: master process /var/nginx/sbin/nginx -c /var/nginx/conf/nginx.conf
nginx 15721 15720 0 17:04 ? 00:00:00 nginx: worker process
nginx 15722 15720 0 17:04 ? 00:00:00 nginx: worker process
nginx 15723 15720 0 17:04 ? 00:00:00 nginx: worker process
nginx 15724 15720 0 17:04 ? 00:00:00 nginx: worker process
root 15728 9963 0 17:04 pts/1 00:00:00 grep --color=auto nginx
# 发送HUP信号给旧的master进程,准备回滚
kill -HUP 9412
# 查看进程状况
ps -ef | grep nginx
nginx 9412 1 0 15:12 ? 00:00:00 nginx: master process /var/nginx/sbin/nginx -c /var/nginx/conf/nginx.conf
nginx 15720 9412 0 17:04 ? 00:00:00 nginx: master process /var/nginx/sbin/nginx -c /var/nginx/conf/nginx.conf
nginx 15721 15720 0 17:04 ? 00:00:00 nginx: worker process
nginx 15722 15720 0 17:04 ? 00:00:00 nginx: worker process
nginx 15723 15720 0 17:04 ? 00:00:00 nginx: worker process
nginx 15724 15720 0 17:04 ? 00:00:00 nginx: worker process
nginx 15737 9412 0 17:05 ? 00:00:00 nginx: worker process
nginx 15738 9412 0 17:05 ? 00:00:00 nginx: worker process
nginx 15739 9412 0 17:05 ? 00:00:00 nginx: worker process
nginx 15740 9412 0 17:05 ? 00:00:00 nginx: worker process
root 15742 9963 0 17:05 pts/1 00:00:00 grep --color=auto nginx
# 发送QUIT信号给新的master进程,彻底退出新的master进程
kill -QUIT 15720
# 查看进程状况
ps -ef | grep nginx
nginx 9412 1 0 15:12 ? 00:00:00 nginx: master process /var/nginx/sbin/nginx -c /var/nginx/conf/nginx.conf
nginx 15737 9412 0 17:05 ? 00:00:00 nginx: worker process
nginx 15738 9412 0 17:05 ? 00:00:00 nginx: worker process
nginx 15739 9412 0 17:05 ? 00:00:00 nginx: worker process
nginx 15740 9412 0 17:05 ? 00:00:00 nginx: worker process
root 15752 9963 0 17:06 pts/1 00:00:00 grep --color=auto nginx
升级成功——彻底退出旧nginx的master进程
kill -QUIT 9412