依赖:http、cjson
http.lua、http_connect.lua、http_headers.lua
这些文件拷贝到/usr/local/openresty/lualib/resty/
nginx中的设置
nginx.conf
lua_package_path "/usr/local/nginx/lua/?.lua;;";
lua_package_cpath "/usr/local/openresty/lualib/?.so;;";
lua_shared_dict dis_cache 10m; #启用nginx共享缓存
http项目 server 配置
1、请求跳转关系,经过验证后将跳转关系写入nginx共享缓存。
这个可以定时执行,或变更跳转关系后,主动刷新。
location /get_nginx_uris/test{
content_by_lua '
local getNginxUris = require("GetNginxUris")
local httpUrl = "http://127.0.0.1:8106/rest/system/listForNginx.htm"
local tempFileName = "/usr/local/nginx/nginx_uris_test.txt"
local finalFileName = "/usr/local/nginx/etc/test.json"
local resBody = getNginxUris.getUriConfig(httpUrl,tempFileName,finalFileName)
ngx.say(resBody)
';
}
为实现跳转,需要有三个location
#入口
location /member/ {
proxy_pass http://172.1.15.16:8090/member/;
rewrite_by_lua_file lua/UrlRedirect.lua;
}
#没有跳转关系,进入
location @old_member {
proxy_pass http://172.1.15.16:8090;
}
#--新项目,有跳转关系,且指定@to_new_member的跳转到这
location @to_new_member {
proxy_pass http://172.1.15.18:8500;
}
lua代码1、地址跳转关系
GetNginxUris.lua文件,目的: 获得新旧地址跳转关系数据,并将关系存入nginx缓存
local http = require "resty.http"
local cjson = require ("cjson")
local urlMapping = require("UrlMapping")
local getNginxUris={}
--请求地址,返回响应
-- 参数 httpUrl 请求url
function getNginxUris.getResponse(httpUrl)
local httpc = http.new()
local res, err = httpc:request_uri(httpUrl, {
method = "get"
})
if not res then
ngx.log(ngx.WARN,"failed to request: ", err)
return 'notok'
else
ngx.status = res.status
if ngx.status ~= 200 then
ngx.log(ngx.WARN,"非200状态,ngx.status:"..ngx.status)
return 'notok'
else
local resStr = res.body
return resStr
end
end
end
-- 根据地址请求转发配置,通过验证后,存入本地etc配置文件
-- 参数 httpUrl 请求地址
-- 参数 tempFileName 临时文件
-- 参数 finalFileName 最终文件
function getNginxUris.getUriConfig(httpUrl,tempFileName,finalFileName)
local moduleKey = ngx.var.host
local resBody = getNginxUris.getResponse(httpUrl)
if(resBody == nil ) then
ngx.log(ngx.ERR,"failed to request: "..httpUrl)
elseif(resBody == 'notok') then
ngx.log(ngx.ERR,"failed to request: "..notok)
else
local resJson = cjson.encode(resBody)
local file = io.open(tempFileName, "w");
assert(file);
file:write(resBody);
file:close();
urlMapping.loadJsonConf(tempFileName)
local urlRelation = urlMapping.getUrlRelation()
local tableSize = urlMapping.getTableLen(urlRelation)
if( tableSize ==nil )
then
ngx.log(ngx.ERR,"&&&&&&&&&&&&---缓存失败---&&&&&&&&&&&"..tableSize)
else
getNginxUris.saveToNginxCache(moduleKey,urlRelation,tableSize)
getNginxUris.newContentFile(finalFileName,resBody)
ngx.log(ngx.ERR,"**************---缓存成功---****************"..tableSize)
end
end
return resBody
end
-- 将结果保存到文件
-- 参数 saveFileName 文件名
-- 参数 resBody 内容
function getNginxUris.newContentFile(saveFileName,resBody)
local file = io.open(saveFileName, "w");
assert(file);
file:write(resBody);
file:close();
end
-- 保存到nginx缓存
function getNginxUris.saveToNginxCache(moduleKey,urlRelation,tableSize)
local cache_ngx = ngx.shared.dis_cache;
cache_ngx:set(moduleKey.."-size", tableSize,0);
for k, v in pairs(urlRelation) do
for k1, v1 in pairs(v) do
local cacheKey = moduleKey.."-"..k1;
cache_ngx:set(cacheKey, v1,0);
end
end
end
return getNginxUris
lua代码2、地址关系解析工具
UrlMapping.lua
local cjson = require ("cjson")
local urlMapping={}
local urlRelation={}
function urlMapping.getUrlRelation()
return urlRelation;
end
function urlMapping.getTableLen(t)
local leng=0
for k, v in pairs(t) do
leng=leng+1
end
return leng;
end
function urlMapping.printTable(t)
for k, v in pairs(t) do
for k1, v1 in pairs(v) do
print(k1,v1)
end
end
end
function urlMapping.trim(str)
str = string.gsub(str, "^[%s]*(.-)[%s]*$", "%1")
return str
end
function urlMapping.split(fullString, separator)
local nFindStartIndex = 1
local nSplitIndex = 1
local nSplitArray = {}
while true do
local nFindLastIndex = string.find(fullString, separator, nFindStartIndex)
if not nFindLastIndex then
nSplitArray[nSplitIndex] = string.sub(fullString, nFindStartIndex, string.len(fullString))
break
end
nSplitArray[nSplitIndex] = string.sub(fullString, nFindStartIndex, nFindLastIndex - 1)
nFindStartIndex = nFindLastIndex + string.len(separator)
nSplitIndex = nSplitIndex + 1
end
return nSplitArray
end
function urlMapping.getLines(filename)
local indx = 0
for line in io.lines(filename) do
indx = indx + 1
local sepIndex = string.find(line, "=", 1)
if(sepIndex ~= nil)
then
local key = string.sub(line, 0 ,sepIndex-1)
key = urlMapping.trim(key)
local commentFlag = string.sub(key,0, 1)
if(commentFlag ~= '#')
then
local value = string.sub(line,sepIndex+1,string.len(line))
value = urlMapping.trim(value)
urlRelation[key] = value
print("key="..key,"value="..urlRelation[key])
end
end
end
return indx, urlRelation --returns number of lines and line table
end
function urlMapping.readJsonFile(filename)
local file = io.open(filename,"r")
local json = file:read("*a");
file:close()
return json
end
function urlMapping.loadConf(filename)
local tableSize = urlMapping.getTableLen(urlRelation)
if (tableSize==0)
then
urlMapping.getLines(filename)
end
end
function urlMapping.loadJsonConf(filename)
local tableSize = urlMapping.getTableLen(urlRelation)
if (tableSize==0)
then
local jsonString = urlMapping.readJsonFile(filename)
urlRelation = cjson.decode(jsonString)
print(type(urlRelation))
urlMapping.printTable(urlRelation)
end
end
function urlMapping.getURL(uri)
for k, v in pairs(urlRelation) do
if(type(v)== 'table')
then
for k1, v1 in pairs(v) do
if(k1 == uri)
then
return v1
end
end
else
return urlRelation[uri]
end
end
-- return urlRelation[uri]
end
return urlMapping
lua代码3、根据地址关系进行跳转的核心代码
UrlRedirect.lua
local request_method = ngx.var.request_method
local methodType = ngx.HTTP_GET
local headers = ngx.req.get_headers()
local cookie = headers.cookie
local body = {
url = ngx.var.uri,
query = ngx.req.get_uri_args(),
type = request_method,
post = nil
}
if "POST" == request_method then
ngx.req.read_body()
body.post = ngx.req.get_post_args()
methodType = ngx.HTTP_POST
end
-- 从nginx缓存中获得跳转地址设置
local moduleKey = ngx.var.host
local cacheKey = moduleKey.."-"..body.url;
local cache_ngx = ngx.shared.dis_cache;
-- local redirect_uri = urlMapping.getURL(cacheKey)
local redirect_uri = cache_ngx:get(cacheKey)
--根据跳转设置进行转发处理
if (redirect_uri ~= nil)
then
local urlArray = urlMapping.split(redirect_uri,",@")
redirect_uri = urlArray[1]
local arraySize = urlMapping.getTableLen(urlArray)
if(arraySize<=1)
then
-- 内部跳转
ngx.log(ngx.ERR,"++++++++++++111111++++++++++++")
ngx.log(ngx.ERR," redirect-yes url= "..redirect_uri)
ngx.exec(redirect_uri, body.query)
else
-- 转到指定location
local anotherLocation = urlArray[2]
ngx.log(ngx.ERR,"++++++++++++222222++++++++++++")
ngx.log(ngx.ERR,"another Location="..anotherLocation," redirect-no url= "..redirect_uri)
ngx.req.set_uri(redirect_uri, false)
ngx.exec("@"..anotherLocation)
end
else
-- 转到默认location
ngx.log(ngx.ERR,"++++++++++++33333++++++++++++")
ngx.log(ngx.ERR," redirect-no url= "..body.url)
ngx.exec("@old_member")
end