nginx 安装第三方模块(lua)并热升级
需求:
nginx上将特定请求拒绝,并返回特定值。
解决办法:
使用lua脚本,实现效果。
操作步骤:
- 安装Luajit环境
- 重新编译nginx(目标机器上
nginx -V
配置一致,并新增两个模块ngx_devel_kit
,lua-nginx-module
) - 热升级(不中断服务)或重启
配置文件添加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操作顺序:
- 检测配置是否正确
- 错误,则不应用新的配置,还是使用老的配置
- 正确,使用新的配置,并新建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
之后,所有工作进程(旧的和新的)继续接受请求。如果WINCH
或QUIT
信号发送到第一个主进程,它将向其工作进程发送消息,要求它们正常关闭,然后它们将开始退出:
[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
nginx 安装第三方模块(lua)并热升级的更多相关文章
- nginx 安装第三方 模块
查看nginx在安装时开启了哪些模块 如果你nginx是rpm包安装的,直接用如下命令nginx -V 如果你是源码包编译安装,假如你的安装路径是/usr/local/nginx,那么你可以使用: / ...
- nginx安装第三方模块
原已经安装好的nginx,现在需要添加一个未被编译安装的模块 举例说明:安装第三方的ngx_cache_purge模块(用于清除指定URL的缓存) nginx的模块是需要重新编译nginx,而不是像a ...
- nginx安装第三方模块的方法
nginx第三方模块安装方法: ./configure --prefix=/你的安装目录 --add-module=/第三方模块目录 以安装fair模块实例 下载fair安装包并解压 1.在未安装ng ...
- nginx安装第三方模块echo
要使用第三方模块ngx_echo的功能,请重新配置添加到nginx插件中 ##下载第三方模块 wget https://github.com/openresty/echo-nginx-module/a ...
- nginx安装第三方模块echo-nginx-module
cd ~ wget -S https://github.com/agentzh/echo-nginx-module/archive/master.zip mv master echo-nginx-mo ...
- nginx增加第三方模块
增加第三方模块 ============================================================ 一.概述nginx文件非常小但是性能非常的高效,这方面完胜ap ...
- Nginx编译安装第三方模块http_substitutions_filter_module2222
Nginx编译安装第三方模块http_substitutions_filter_module Rming -- 阅读 安装 Http 编译 module filter nginx 模块 >> ...
- Nginx编译安装第三方模块http_substitutions_filter_module
Nginx编译安装第三方模块http_substitutions_filter_module 分类:服务器技术 作者:rming 时间:-- . >>ngx_http_substitu ...
- Nginx安装echo模块
echo-nginx-module 模块可以在Nginx中用来输出一些信息,可以用来实现简单接口或者排错. 项目地址:https://github.com/openresty/echo-nginx-m ...
随机推荐
- LeetCode 102. Binary Tree Level Order Traversal02. 二叉树的层次遍历 (C++)
题目: Given a binary tree, return the level order traversal of its nodes' values. (ie, from left to ri ...
- NOIP 2003 神经网络
洛谷 P1038 神经网络 https://www.luogu.org/problemnew/show/P1038 JDOJ 1278: [NOIP2003]神经网络 T1 https://neooj ...
- Web协议详解与抓包实战:HTTP1协议-详解请求行(2)
一.请求行一 二.请求行二 三.请求行三 四.常见方法(RFC7231) 实际测试截图 五.用于文档管理的 WEBDAV 方法(RFC2518) 六.WEBDAV 验证环境 1.登录 2.Wire ...
- oracle--oracle18C DG搭建(二)
配置清单 任务 数据库 创建主数据库数据文件的备份副本 主 为备用数据库创建控制文件 主 为备用数据库创建参数文件 主 将文件从主系统复制到备用系统 主 设置环境以支持备用数据库 备库 启动物理备用数 ...
- Visual Studio 调试系列5 检查变量(使用自动窗口和局部变量窗口)
系列目录 [已更新最新开发文章,点击查看详细] 在调试时,“自动变量”和“局部变量”窗口会显示变量值. 仅在调试会话期间,这两个窗口才可用. “自动变量”窗口显示当前断点周围使用的变量. “局 ...
- 【Struts】Struts框架配置详解
1.首先将所必须的Jar包放到项目的WebRoot/WEB-INF/lib目录下. 如果你没有这些Jar文件,你可以到Struts官网上下载:http://struts.apache.org/.因为经 ...
- golang web 方案
概要 开发 web 框架 数据库 认证 日志 配置 静态文件服务 上传/下载 发布 docker 打包 部署中遇到的问题 时区问题 概要 轻量的基于 golang 的 web 开发实践. golang ...
- 判断一个类型是否为可空类型 System Nullable
bool IsNullableType(Type theType) { return (theType.IsGenericType && theType. G ...
- 程序员需要了解的linux常用命令
网络 找出某程序(tomcat)的进程 ps -ef|grep tomcat 找出后如果要关闭 kill -9 pid统计某程序(tomcat)连接数 ps -ef|grep tomcat|w ...
- MyBatis 通过 BATCH 批量提交
本文由 简悦 SimpRead 转码, 原文地址 https://www.jb51.net/article/153382.htm 很多人在用 MyBatis 或者 通用 Mapper 时,经常会问有没 ...