您的位置:首页 > 数据库 > Redis

Openerstry + lua + redis 动态路由转发

一同胡 2020-08-06 19:22 246 查看 https://blog.51cto.com/1403475

# 环境准备

lua环境5.1 以上
安装lua-cjson-2.1.0模块

第一步:下载地址,http://www.kyne.com.au/~mark/software/lua-cjson.php
下载lua-cjson-2.1.0.tar.gz

第二步:解压cjson

sudo tar zxvf lua-cjson-2.1.0.tar.gz

第三步: make
如果出现报错

find / -name lua.h

结果:

/usr/local/openresty/lua/lua-5.3.4/src/lua.h

修改Makefile

第四步:
重新

make
make install

第五步:打开lua终端引入cjson测试

没有报错则成功安装了。

安装Openresty

yum install -y make cmake gcc gcc-c++ autoconf automake libpng-devel libjpeg-devel zlib libxml2-devel ncurses-devel bison libtool-ltdl-devel libiconv libmcrypt mhash mcrypt pcre-devel openssl-devel freetype-devel libcurl-devel readline-devel curl ghostscript

wget https://openresty.org/download/openresty-1.11.2.5.tar.gz
wget https://www.openssl.org/source/openssl-1.0.2g.tar.gz
解压

tar -zxvf openresty-1.11.2.5.tar.gz
tar -zxvf openssl-1.0.2g.tar.gz
cd /usr/local/openssl-1.0.2g

编译安装openssl模块
./config --prefix=/usr/local/openssl
make && make install
cd /usr/local/zlib-1.2.11
./configure  --prefix=/usr/local/zlib

编译安装openresty
make && make install
cd openresty-1.11.2.5
./configure --prefix=/usr/local/openresty --with-luajit --with-http_ssl_module --user=root --group=root --with-http_realip_module --with-pcre --with-http_realip_module --with-zlib=/usr/local/zlib-1.2.8

gmake
gmake install

使用yum安装redis,需要下载阿里云yum源

yum install redis -y

初始化配置就不写了,网上一大片一大片的

接下来才是重点Lua脚本内容

local cjson = require "cjson"
local redis = require "resty.redis"
local pool_max_idle_time = 10001
local pool_size = 100
local red = redis:new()
local ok, err = red:connect('192.168.10.174','6379')
red:set_timeout(1000)
if not ok then
ngx.say("failed to connect: ", err)
return
end
local count, err = red:get_reused_times()

if 0 == count then
local ok, err = red:auth("123456")
if not ok then
ngx.say("failed to auth", err)
return
end
local ok, err = red:select("0")
if not ok then
ngx.say("failed to select db: ", err)
return
end
elseif err then
ngx.say("failed to get reused times:", err)
return
end
local request_uri = ngx.var.request_uri

function spliturl( s, c )
for item in string.gmatch( s, "(.-)"..c) do
urls = item
urls = string.gsub(urls, "^/*(.-)%s*$", "%1")
if not urls then
ngx.say("failed to get urls: ", err)
end
end
end
spliturl(request_uri , "?" )

--domain is ip:prot
local domain, err = red:get(urls)
if not domain then
ngx.exit(404)
--ngx.say("failed to get proxied domain: ", err)
--return
elseif domain == ngx.null then
ngx.exit(404)
end

--获取token
local headers = ngx.req.get_headers()
local token = headers["token"]

--拼接完整的redis key
local redis_key = urls..":"..token
local ok, err = red:select("1")
if not ok then
ngx.say("failed to select db: ", err)
return
end

local getKey  = red:get(redis_key)
--ngx.say(getKey)
if  getKey == ngx.null then
ngx.exit(403)
end

--将获取到的value赋值给target
ngx.var.target = domain
red:close()

nginx配置文件

location ~* ^/ {

#set $request_uri;
#set $args;
proxy_send_timeout   75;
proxy_read_timeout   75;
proxy_buffer_size   4k;
proxy_buffers   4 32k;
proxy_busy_buffers_size   64k;
proxy_temp_file_write_size  64k;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,X-Requested-With';
add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS';
resolver 114.114.114.114;
default_type 'text/plain';
charset 'utf-8';
access_by_lua_file /usr/local/openresty/lua/redis.lua;
set $target '';
proxy_pass http://$target; #$arg_name;
}

使用Postman测试

正确的结果

输入的path,redis会去库中查如果没有该键值时和返回的页面

token错误时返回的结果

希望可以帮助到有需要到同学,有问题可以随时联系我

标签: