java架构师培训:Nginx的平滑升级步骤

2021年01月12日 15:01

32

    为了通知运行中的Nginx进程执行升级,我们必须使用一种进程间通讯的方案。在Linux中,通知进程的最简便方法是信号,Nginx便选择了这一方案。由于热升级涉及到复杂的回滚操作,必须对新老master进程独立的发送信号,因此Nginx决定由管理员通过命令行中的kill命令发送信号,完成热升级或者回滚。


    我们先来看热升级的步骤。升级前,建议你先将老的binary二进制文件后(即/usr/local/nginx/sbin/nginx文件)备份到另一个位置,为后续可能的回滚做准备。接着,你需要把新版本的nginx二进制文件覆盖老文件,这样,运行中的master进程生成子进程后才能载入新版本的nginx。注意,虽然你覆盖了老nginx,但并不会影响运行中的老nginx进程。


    接着,你可以用ps命令找到master进程的pid,并通过kill命令向它发送USR2信号,这样master进程就会生成新的子进程,同时用exec函数载入新版本的nginx二进制文件,并将进程改名为nginx:masterprocess。当然,新的master也会依据nginx.conf中的内容,再次启动新worker子进程提供服务,这些父子进程的关系如下图所示:

5c5958f14da5fef9290dfda5d6bd7744.png

    此时,老版本的nginx已经停止监听80端口,你可以通过netstat命令看到,现在只有新版本的nginx进程会监听80端口了,今后新建立的TCP连接都会由新版本进程处理:

640 (1).png


    那么,如何让老版本的nginx进程在处理完现存TCP连接后退出呢?很简单,使用nginx的优雅退出功能即可,具体通过kill向老master进程发送WINCH或者QUIT信号即可:

640.png

    当老版本的master、worker进程都退出后,根据Linux内核的规则,pid为1的系统守护进程将成为新master的父进程。


    因此,平滑升级Nginx通常会经历3个阶段:


    1、仅老nginx进程在运行,此时先备份nginxbinary文件,再把新版本的nginx覆盖原位置,最后通过kill发送USR2信号。


    2、新老nginx进程同时并存,此时需要通过信号命令老master进程优雅退出。


    3、当处理完所有请求后,老的nginx进程退出,此时平滑升级完毕。


    在新老nginx并存时,如果向老master进程发送了QUIT信号,那么在它的worker子进程退出后,老master进程也会自行退出。这时如果需要从新版本回滚到老版本,就得重新执行一次“升级”。还有一种更简单的回滚方法,向老master进程发送WINCH信号,这样老worker进程全部退出后,老master进程仍然存在。


    由于老master进程是由老版本的nginx二进制文件启动,这样回滚很容易,只要将它的worker进程重新拉起,即可向用户提供旧版本服务,同时要求新版本的Nginx进行优雅退出即可。


    这就是Nginx平滑升级和回滚的全过程,这是我们在大流量生产环境中必须掌握的步骤。


  推荐阅读:jvm培训:如何判断哪些对象需要回收?


更多鲁班学院java高级培训免费课程试听地址https://www.lubanjava.com/course.html

鲁班学院java高级培训课程https://www.lubanjava.com/course/detail/519.html

加群即可领取鲁班学院最新Java高级培训课程资料学习包 群号:700541970



咨询(2)
免费试听
领取优惠
加群交流

扫一扫
加群领取架构师资料

售后反馈
返回顶部