阅读完需:约 5 分钟
Nginx是一个反向代理的组件,在Nginx上可以运行Lua脚本来增强Nginx的能力实现网关拦截,鉴权,限流等功能,这里我们使用Dockerfile来安装会更快。
服务器版本
Linux VM-24-13-centos 3.10.0-1160.11.1.el7.x86_64 #1 SMP Fri Dec 18 16:34:56 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
在服务器上创建一个目录来存放Dockerfile
,这里创建了/home/nginx/
目录来存放相关文件
Dockerfile-Nginx.yml
# nginx Dockerfile
# Version 1.0
# author fendo
# Base images 基础镜像
FROM centos:centos7
#FROM hub.c.163.com/netease_comb/centos:7
#安装相关依赖
RUN yum -y update
RUN yum -y install gcc gcc-c++ autoconf automake make
RUN yum -y install zlib zlib-devel openssl* pcre* wget lua-devel
#ADD 获取url中的文件,放在当前目录下
ADD http://nginx.org/download/nginx-1.14.0.tar.gz /tmp/
#LuaJIT 2.1
#ADD http://luajit.org/download/LuaJIT-2.0.5.tar.gz /tmp/
ADD https://github.com/LuaJIT/LuaJIT/archive/v2.0.5.tar.gz /tmp/
#ngx_devel_kit(NDK)模块
ADD https://github.com/simpl/ngx_devel_kit/archive/v0.3.0.tar.gz /tmp/
#lua-nginx-module 模块
ADD https://github.com/openresty/lua-nginx-module/archive/v0.10.13.tar.gz /tmp/
#nginx ngx_cache_purge模块
ADD http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz /tmp/
#nginx lua-resty-redis-连接单个redis
ADD https://github.com/openresty/lua-resty-redis/archive/refs/tags/v0.29.tar.gz /tmp/
#nginx lua-JSON解析
ADD https://github.com/openresty/lua-cjson/archive/refs/tags/2.1.0.8rc1.tar.gz /tmp/
COPY ./lua-redis-cluster-master /usr/local/src/
#切换目录
WORKDIR /tmp
#安装LuaJIT 2.0.5
#RUN wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz -P /tmp/
RUN tar zxf v2.0.5.tar.gz
WORKDIR /tmp/LuaJIT-2.0.5
#RUN cd LuaJIT-2.0.5
RUN make PREFIX=/usr/local/luajit
RUN make install PREFIX=/usr/local/luajit
#安装ngx_devel_kit(NDK)
WORKDIR /tmp
RUN ls -al
RUN tar -xzvf v0.3.0.tar.gz
RUN cp -r ngx_devel_kit-0.3.0/ /usr/local/src/
#安装lua-nginx-module模块
RUN tar -xzvf v0.10.13.tar.gz
RUN cp -r lua-nginx-module-0.10.13/ /usr/local/src/
#安装nginx ngx_cache_purge模块
RUN tar -xzvf ngx_cache_purge-2.3.tar.gz
RUN cp -r ngx_cache_purge-2.3/ /usr/local/src/
#安装nginx redis模块
RUN tar -xzvf v0.29.tar.gz
RUN cp -r lua-resty-redis-0.29/ /usr/local/src/
#安装nginx json模块
RUN tar -xzvf 2.1.0.8rc1.tar.gz
RUN cp -r lua-cjson-2.1.0.8rc1/ /usr/local/src/
#设置环境变量
RUN export LUAJIT_LIB=/usr/local/lib
RUN export LUAJIT_INC=/usr/local/include/luajit-2.0
RUN mkdir -p {/usr/local/nginx/logs,/var/lock}
#编译安装Nginx
RUN useradd -M -s /sbin/nologin nginx
RUN tar -zxvf nginx-1.14.0.tar.gz
RUN mkdir -p /usr/local/nginx
RUN cd /tmp/nginx-1.14.0 \
&& ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx \
--error-log-path=/usr/local/nginx/logs/error.log \
--http-log-path=/usr/local/nginx/logs/access.log \
--pid-path=/usr/local/nginx/logs/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--with-ld-opt="-Wl,-rpath,/usr/local/luajit/lib" \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-http_sub_module \
--add-module=/usr/local/src/lua-nginx-module-0.10.13 \
--add-module=/usr/local/src/ngx_devel_kit-0.3.0 \
--add-module=/usr/local/src/ngx_cache_purge-2.3 \
&& make && make install
#参数说明
#--prefix 用于指定nginx编译后的安装目录
#--add-module 为添加的第三方模块,此次添加了fdfs的nginx模块
#--with..._module 表示启用的nginx模块,如此处启用了http_ssl_module模块
RUN /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
RUN ln -s /usr/local/nginx/sbin/* /usr/local/sbin/
#EXPOSE 映射端口
EXPOSE 80 443
#CMD 运行以下命令
#CMD ["nginx"]
CMD ["/usr/local/nginx/sbin/nginx","-g","daemon off;"]
在当前目录下执行Dockerfile
docker build -f Dockerfile-Nginx.yml -t centos/nginx:1.0.0 .
构建完成后查看镜像
docker images
启动Nginx镜像
docker run -itd -p 80:80 -p 443:443 centos/nginx:1.0.0 /usr/local/nginx/sbin/nginx -g "daemon off;"
如果启动失败,可进入到镜像中去,通过命令/usr/local/nginx/sbin/nginx启动nginx。
到这里Nginx就启动完成了
访问页面
之后我们来测试Lua脚本在Nginx下的运行
首先进入容器
docker exec -it sweet_goodall /bin/bash
然后进入我们Dockerfile
中指定的nginx.conf
文件进行修改配置
在nginx.conf
中添加Lua的文件
location /test_lua {
default_type 'text/plain';
// 关闭脚本缓存,这样修改脚本就不需要重启Nginx
lua_code_cache off;
content_by_lua_file ' /usr/local/nginx/conf/demo.lua';#jq.lua脚本的存放地址
}
访问页面
当Lua脚本与Nginx测试成功后,我们可以开始测试Lua与redis的连接
这里的连接有两个Lua的包可以下载引用
单机的redis
https://github.com/openresty/lua-resty-redis
demo.lua
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by xujiahui.
--- DateTime: 2022/6/23 17:35
---
package.path = "/usr/local/nginx/conf/lua-resty-redis-master/lib/?.lua;;"; --扩展包的路径按自己的路径进行修改
local redis = require("resty.redis")
local red = redis:new()
red:set_timeout(1000)
local ip = "82.157.173.74"
local port = 6379
red:connect(ip, port)
red:set("msg", "hello world")
local resp = red:get("msg")
ngx.say("msg : ", resp)
集群的redis
https://github.com/onlonely/lua-redis-cluster
demo.lua
--引入redis-cluster扩展包
package.path ="/home/sms/zhupy/lua-redis-cluster-master/?.lua;;" --扩展包的路径按自己的路径进行修改
ngx.header.content_type="text/plain";
-- 构建redis集群
local function redis_cluster_init ()
local redis_cluster = require "resty.redis_cluster"
local cluster_id = "mymaster"
local startup_nodes = {
{"192.168.150.131",6000},--集群 主机
{"192.168.150.132",6000}--集群 从机
}
local opt = {
timeout = 1000,--执行超时时间
keepalive_size = 50,--长连接数量
keepalive_duration = 60000, --长连接保持时间
auth="aaa", --设置密码
}
rc = redis_cluster:new(cluster_id, startup_nodes, opt)
return rc
end
local redis = redis_cluster_init();
--字符串按指定符号分割的方法
function string.split(input, delimiter)
input = tostring(input)
delimiter = tostring(delimiter)
if (delimiter=='') then return false end
local pos,arr = 0, {}
-- for each divider found
for st,sp in function() return string.find(input, delimiter, pos, true) end do
table.insert(arr, string.sub(input, pos, st - 1))
pos = sp + 1
end
table.insert(arr, string.sub(input, pos))
return arr
end
--得到请求地址的url 并分割
local res = string.split(ngx.var.uri, "/")
--ngx.say(res)
--ngx.say("====res1",res[1])
--ngx.say("====res2",res[2])
--ngx.say("===res3",res[3])
--ngx.say("===res3",res[4])
local key=res[3];--得到appShortName
local field=res[4];-- 得到主键id
local url,err=redis:hget(key,field)--获取hash格式的值
if not url then
url=""
end
if url == ngx.null then
url = "";
end
--获取到redis中的文件地址后直接进行跳转
return ngx.redirect(url)