• nginx热升级


    做web开发和做运维的都知道nginx是一个非常优秀的web服务器和反向代理服务器,它优秀的多进程架构保证其稳定的运行,还为我们提供了热升级功能(不影响客户端请求的处理)。

    1. nginx热升级介绍

    nginx热升级也就是在不影响客户端请求(服务不中断)的情况下使用新的nginx二进制文件替换老的nginx二进制文件在停掉老的进程。

    这种热升级得益于nginx的多进程架构设计,能够在老的nginx主进程不退出的情况下以子进程的方式启动新的master进程和新的woker进程,让新的master进程重新监听端口和接收请求。新的master进程稳定之后,通过发送信号的方式通知老master进程退出。完成整个热升级。

    2. nginx热升级流程

    2.1 准备新的nginx二进制文件

    通过编译得到新的nginx二进制文件,注意为了能够完成升级编译时必须保持和老的nginx配置文件路径、日志路径、pid文件路径等保持一致,否则会导致nginx配置失效!

    以下面的我的演示环境为例,目前我的nginx版本以及配置路径如下:

    $ ./nginx -v
    nginx version: nginx/1.22.0
    
    • 1
    • 2
    prefix=/home/geng/nginx
    
    /home/geng/nginx
    ├── client_body_temp
    ├── conf
    │   ├── nginx.conf
    │   └──.......
    ├── fastcgi_temp
    ├── html
    │   ├── 50x.html
    │   └── index.html
    ├── logs
    │   ├── access.log
    │   ├── error.log
    │   └── nginx.pid
    ├── proxy_temp 
    ├── sbin
    │   ├── nginx
    ├── scgi_temp
    └── uwsgi_temp 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    现在要升级到1.23.1版本,
    下载地址http://nginx.org/download/nginx-1.23.1.tar.gz,使用wget工具下载

    wget http://nginx.org/download/nginx-1.23.1.tar.gz
    
    • 1

    解压进入目录执行:

    $ ./configure --prefix=/home/geng/nginx
    $ make
    
    • 1
    • 2

    注意:这里指定的安装路径前缀和老的nginx保持一致!

    如果执行make没有报错的话在目录的objs目录下就会生成nginx二进制文件。
    至此准备工作已经完成。

    2.2 替换老的nginx二进制文件

    为了方便对比,当前nginx的版本还是1.22.0
    在这里插入图片描述
    进入nginx的sbin目录,备份nginx二进制文件为nginx.oldbin

    $ ls
    nginx
    $ mv nginx nginx.oldbin
    $ ls
    nginx.oldbin
    
    • 1
    • 2
    • 3
    • 4
    • 5

    拷贝新的nginx二进制文件到sbin目录:

    $ cp ~/nginx-1.23.1/objs/nginx ./
    $ ls
    nginx  nginx.oldbin
    
    • 1
    • 2
    • 3

    2.3 通知老的nginx master进程启动新的nginx master进程

    nginx进程间通过系统信号进行通信。
    要想通知老的nginx master进程启动新的nginx master进程,只需发送USR2的系统信号到老的nginx进程。
    首先查看一下nginx进程号:

    $ ps -ef |grep nginx
    root      8267    10  0 20:08 ?        00:00:00 nginx: master process ./nginx
    nobody    8268  8267  0 20:08 ?        00:00:00 nginx: worker process
    geng      8678  8599  0 20:45 pts/1    00:00:00 grep --color=auto nginx
    
    • 1
    • 2
    • 3
    • 4

    8267就是nginx主进程号,它只有一个worker进程(pid:8268)。

    使用kill命令发送信号(USR2对应的信号为12,如果记不住可以使用kill -l查看):

    $ sudo kill -12 8267
    
    • 1

    此时查看nginx进程:

    $ ps -ef |grep nginx
    root      8267    10  0 20:08 ?        00:00:00 nginx: master process ./nginx
    nobody    8268  8267  0 20:08 ?        00:00:00 nginx: worker process
    root      8681  8267  0 20:47 ?        00:00:00 nginx: master process ./nginx
    nobody    8682  8681  0 20:47 ?        00:00:00 nginx: worker process
    geng      8684  8599  0 20:49 pts/1    00:00:00 grep --color=auto nginx
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    发现有两个master进程,第二个master进程就是新的主进程,并且是作为老进程的子进程启动的。
    并且nginx会将老的pid文件命名为nginx.pid.oldbin。

    其实此时再有新的连接进来,就由新的主进程和新的worker进程处理了。

    我们访问一下就能验证:
    在这里插入图片描述

    那为什么老的nginx进程为什么不主动退出呢?
    这是因为当我们新的nginx二进制文件有问题或需要回滚时,方便我们直接回退到老的nginx。
    只需通过向老的信号发送信号“SIGHUP (1)”,然后向新的进程发送信号“SIGQUIT (3)”将新的进程退出。

    $ sudo kill -1 8267
    $ sudo kill -3 8681
    $ ps -ef |grep nginx
    root      8267    10  0 20:08 ?        00:00:00 nginx: master process ./nginx
    nobody    8268  8267  0 20:08 ?        00:00:00 nginx: worker process
    nobody    8692  8267  0 20:57 ?        00:00:00 nginx: worker process
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    访问一下,发现已经退回到1.22.0版本了!

    2.4 退出老的master进程

    新的master进程如果没有问题,就可以退出老的进程了。
    只需通过向老的进程发送信号“SIGQUIT (3)”,老的进程就会优雅的退出。

    $ sudo kill -3 8267
    $ ps -ef |grep nginx
    root      8681  10  0 20:47 ?        00:00:00 nginx: master process ./nginx
    nobody    8682  10  0 20:47 ?        00:00:00 nginx: worker process
    
    • 1
    • 2
    • 3
    • 4

    此时只剩新的进程了。

    注意:有些时候由于老的进程中还有请求没处理玩可能不能立即退出,此时查看进程可能是下面的结果:

     root      8267    10  0 20:08 ?        00:00:00 nginx: master process ./nginx
     nobody    8268  8267  0 20:08 ?        00:00:00 nginx: worker process is shutting down
     nobody    8692  8267  0 20:57 ?        00:00:00 nginx: worker process is shutting down
    
    • 1
    • 2
    • 3

    正常情况,当worker进程处理完请求就会连带老的master进程一起退出。

    至此nginx热升级完成。

    3. nginx热升级流程总结

    一般使用下面的流程:

    1. 备份老的准备nginx二进制文件
    2. 准备新的nginx二进制文件,新的nginx二进制各配置路径保持一致
    3. 向老的nginx进程发送“SIGUSR2 (12)”信号,启动新的进程(新老进程并存)
    4. 向老的nginx进程发送“SIGQUIT (3)”信号停掉老的nginx进程
  • 相关阅读:
    Linux----硬链接与符号链接(软链接)
    TypeError: Object of type bool_ is not JSON serializable(PKL转json)
    【Java】Apache HttpClient调用微信支付API v3报错:找不到证书序列号对应的证书
    唉,现在说什么都晚了,真没想到,2022年就要过完了
    2022/9/14(cf·div3)https://codeforces.com/contest/1729
    C++系列-递增运算符重载
    如何将项目打包上传到NuGet服务器(图文教程)?
    第一节 vue3 router内置类型有哪些
    亚马逊攀岩绳EN892标准安全测试
    8-Arm PEG-DBCO,八臂-聚乙二醇-二苯基环辛炔,用于修饰生物分子
  • 原文地址:https://blog.csdn.net/gybshen/article/details/126562111