zoukankan      html  css  js  c++  java
  • nginx 安装第三方模块(lua)并热升级

    需求:

    nginx上将特定请求拒绝,并返回特定值。

    解决办法:

    使用lua脚本,实现效果。

    操作步骤:

    1. 安装Luajit环境
    2. 重新编译nginx(目标机器上nginx -V 配置一致,并新增两个模块ngx_devel_kit,lua-nginx-module)
    3. 热升级(不中断服务)或重启

    配置文件添加lua脚本:

    #匹配请求体里的 hello=world时返回此变量和值
      location /hello {
        rewrite_by_lua_block {
        ngx.req.read_body()
        local own_a = ngx.req.get_post_args()["hello"]
        if ( own_a == "world" ) then
          ngx.say("hello world")
        end
        }
        proxy_pass  xxxx;
      }
    

    一、安装Luajit环境

    #安装lua-nginx模块需要先安装Luajit
    $ tar xf LuaJIT-2.0.4.tar.gz 
    $ cd LuaJIT-2.0.4
    $ make PREFIX=/usr/local/luajit
    $ make install PREFIX=/usr/local/luajit
    
    $ cat <<EOF > /etc/profile.d/luajit.sh
    export LUAJIT_LIB=/usr/local/luajit/lib
    export LUAJIT_INC=/usr/local/luajit/include/luajit-2.0
    EOF
    
    $ source /etc/profile.d/luajit.sh
    
    #判断是否有库函数链接
    if [ ! -f /lib64/libluajit-5.1.so.2 ];then
    	ln -s /usr/local/luajit/lib/libluajit-5.1.so.2 /lib64/libluajit-5.1.so.2
    fi
    #添加库函数链接
    if [ ! -f /lib64/libprofiler.so.0 ];then
    	ln -sv /usr/local/lib/libprofiler.so.0.4.18 /lib64/libprofiler.so.0 || echo "/usr/local/lib/libprofiler.so.0.4.18 fasle,please check this" 
    fi
    #可以使用 ldd $(which /usr/local/nginx/sbin/nginx) 查看缺少的库文件
    
    

    二、编译二进制文件

    可在测试机(目标机器环境相同)编译好最新的nginx二进制文件(nginx -V相同并且新增两个模块即可)。也可直接在目标机器上编译,但是最后make install 不可执行,否则就覆盖目标环境了。

    目标环境:

    #将生成的nginx二进制文件替换至目录机器
    $ cd /usr/loca/nginx/sbin/
    $ mv nginx{,_bak}   #先备份老的
    $ mv /home/install_nginx/src/nginx ./    #将新的移动过来
    $ nginx -t    #检查配置,这一步很重要,一但报错,说明nginx二进制文件编译有问题,需要重新核对环境信息并重新编译
    nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
    nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
    
    $ nginx -s reload
    $
    $ curl -d "hello=world" http://192.168.20.13/hello
    xxx                                 #返回结果不是hello world,lua脚本配置未生效。此时老的配置并不影响
    

    查看错误日志:

    2019/10/08 17:25:22 [notice] 30580#0: signal process started
    2019/10/08 17:25:22 [emerg] 22066#0: unknown directive "rewrite_by_lua_block" in /usr/local/nginx/conf/vhost/text.conf:41
    

    未识别rewrite_by_lua_block 配置,说明lua脚本配置未生效。看来nginx -s reload是不行,只能通过热升级了。

    nginx启动时master进程会初始化每个模块的信息,reload只是重新开启新的worker进程。所以新增模块只能重启或热升级。

    nginx 信号:

    信号 nginx内置shell 说明
    HUP nginx -s reload 重载配置文件
    USR1 nginx -s reopen 重新打开日志文件,配置mv,用做日志切割
    USR2 - 热升级nginx程序
    WINCH - 优雅的关闭相关的worker进程
    QUIT nginx -s squit 优雅的停止nginx
    TERM,INT nginx -s stop 立即停止nginx

    nginx -s reload 执行后的nginx操作顺序:

    1. 检测配置是否正确
    • 错误,则不应用新的配置,还是使用老的配置
    • 正确,使用新的配置,并新建worker进程,并通知老的worker进程优雅的关闭

    发送热升级信号:

    $ kill -USR2 `cat /tmp/nginx.pid`
    $
    #执行完后查看进程,调接口都没生效
    ##查看error log
    2019/10/08 17:25:41 [alert] 30599#0: execve() failed while executing new binary process "nginx" (2: No such file or directory)
    
    

    上面的报错: 找不到nginx命令。nginx程序依赖环境变量,而上一次启动肯定不是用绝对路径启动(nginx命令直接启)。这种情况就无法做热升级,只能restart了,restart后配置即生效,接口调通了。

    正确的nginx热升级步骤

    [root@node2013 vhost]# /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf   #正确的启动nginx
    
    

    重新执行编译nginx步骤,为了升级服务器可执行文件,应首先将新的可执行文件替换旧文件。之后,USR2信号应发送到主进程。主进程首先将其具有进程ID的文件重命名为带有.oldbin后缀的新文件,例如 /tmp/nginx.pid.oldbin,然后启动一个新的可执行文件,该文件又启动新的工作进程:

    [root@node2013 vhost]# kill -USR2 `cat /tmp/nginx.pid`  #发送热升级信号
    [root@node2013 vhost]# ps -ef | grep nginx            
    root     31118     1  0 17:36 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
    nobody   31119 31118  0 17:36 ?        00:00:00 nginx: worker process
    nobody   31120 31118  0 17:36 ?        00:00:00 nginx: worker process
    nobody   31121 31118  0 17:36 ?        00:00:00 nginx: worker process
    nobody   31122 31118  0 17:36 ?        00:00:00 nginx: worker process
    root     31177 31118  0 17:36 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
    nobody   31178 31177  0 17:36 ?        00:00:00 nginx: worker process
    nobody   31179 31177  0 17:36 ?        00:00:00 nginx: worker process
    nobody   31180 31177  0 17:36 ?        00:00:00 nginx: worker process
    nobody   31181 31177  0 17:36 ?        00:00:00 nginx: worker process
    root     31185 30078  0 17:37 pts/0    00:00:00 grep --color=auto nginx
    [root@node2013 vhost]# ll /tmp/
    total 12
    -rw-r--r-- 1 root   root     6 Oct  8 17:36 nginx.pid
    -rw-r--r-- 1 root   root     6 Oct  8 17:36 nginx.pid.oldbin
    
    $ curl -d "hello=world" http://192.168.20.13/hello  #正常返回结果,lua脚本生效。如未生效则直接发送`QUIT`信号给新的master进程。
    hello world
    

    之后,所有工作进程(旧的和新的)继续接受请求。如果WINCHQUIT信号发送到第一个主进程,它将向其工作进程发送消息,要求它们正常关闭,然后它们将开始退出:

    [root@node2013 vhost]# kill -QUIT `cat /tmp/nginx.pid.oldbin`       #优雅的退出进程
    [root@node2013 vhost]# ps -ef | grep nginx              #最后查看效果,只剩下新的master和其worker进程
    root     31177     1  0 17:36 ?        00:00:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
    nobody   31178 31177  0 17:36 ?        00:00:00 nginx: worker process
    nobody   31179 31177  0 17:36 ?        00:00:00 nginx: worker process
    nobody   31180 31177  0 17:36 ?        00:00:00 nginx: worker process
    nobody   31181 31177  0 17:36 ?        00:00:00 nginx: worker process
    root     31254 30078  0 17:38 pts/0    00:00:00 grep --color=auto nginx
    [root@node2013 vhost]# 
    

    总结:

    nginx启动须使用绝对路径,不然无法处理USR2信号。

    文档链接:
    nginx 安装lua模块: https://github.com/openresty/lua-nginx-module#installation
    nginx 信号: http://nginx.org/en/docs/control.html
    nginx main初始化:https://blog.csdn.net/time_change/article/details/78470901

  • 相关阅读:
    初始化和实例化对象
    java设计模式
    构造方法的访问级别
    C#连接操作sqlite
    using三种用法
    C#获取当前日期时间
    C#生成excel到其他电脑生成报表时报错
    [Python] VSCode隐藏__pycache__文件夹
    [Git] 常用操作速查
    [Pytorch] 卷积尺寸计算
  • 原文地址:https://www.cnblogs.com/dance-walter/p/11640700.html
Copyright © 2011-2022 走看看