nginx OpenResty lua resty http 代理网关从无到有搭建

一、背景说明
准备在项目中基于nginx、OpenResty搭建一个简易网关,实现同一域名根据不同cookie代理不同docker功能,降低前端、移动端多业务线并行测试联调成本。简单来说就是服务端有多个测试环境docker分别部署不同业务需求代码,通过在前端、移动端种植cookie(存放服务端测试环境docker IP地址)方式让其具有可选择服务端测试环境能力,大大降低联调环境配置成本。具体cookie的解析逻辑在nginx中使用lua实现。

二、lua中读写header、cookie 代码

---获取请求header
local reqHeaders = ngx.req.get_headers();
---获取请求cookie
local reqCookie = reqHeaders["cookie"];
--读取cookie值
local pcip = ngx.var.cookie_pcip;
pcip=reqCookie["pcip"];
--设置赋值cookie
ngx.header['Set-Cookie']={"pcip=127.0.0.1;domain=.timer.com;path=/" }

注:在nginx.header['Set-Cookie'] 时遇到一个问题,一次性种植多个cookie时,会出现无法一次性全部种植成功的情况,需要多次请求种植方能全部种植成功,在实战中请慎用。尤其在ngx.say()方法调用之前种植cookie出现无法一次种植成功现象几率大,在ngx.print()方法调用之前种植cookie也会如此。
其他辅助代码:

--获取请求URI
local requestUri = ngx.var.request_uri;
--获取请求域名
local requestHost = ngx.var.host;
----获取请求方法类型GET POST
local reqType= ngx.var.request_method;
--打印日志
ngx.log(ngx.ERR, ',requestHost:'..requestHost);
--反馈客户端信息
ngx.print("反馈输出纯文本");
ngx.say("反馈输出页面");

三、lua 脚本中嵌入 resty.http 文件,在lua中借助于resty.http代理http请求
resty.http (http.lua和http_headers.lua)文件下载地址:https://github.com/ledgetech/lua-resty-http/tree/master/lib/resty

--引入resty.http文件
package.path = package.path..';/export/Instances/timer/lua/resty/?.lua;'
local myHttp = require "http"
---Get 请求
local function http_get(url,headerParm,timeout)
    local httpc = myHttp.new();
    timeout = timeout or 30000;
    httpc:set_timeout(timeout)
    local res, err_ = httpc:request_uri(url, {
        method = "GET",
        keepalive=false,
        headers = headerParm;
    })
    httpc:set_keepalive(5000, 100);
    ---httpc:close();
    return res,err_;
end
---Post 请求
local function http_post(url,headerParm,body,timeout)
    local httpc = myHttp.new();
    timeout = timeout or 30000;
    httpc:set_timeout(timeout);
    local res, err_ = httpc:request_uri(url, {
        method = "POST",
        body = body,
        keepalive=false,
        headers =  headerParm;
    })
    httpc:set_keepalive(5000, 100)
    ---httpc:close();
    return res,err_;
end

在lua脚本中根据请求类型代理Http请求:

---请求路径
local reqUrl ="代理的请求URL地址";
----请求类型
local reqType= ngx.var.request_method;
--读取reqResult返回结果中的header 信息,赋值给nginx的Response header中
local function setResHeader(res)
    if(res ~= nil)then
        for k,v in pairs(res.headers) do
            ngx.header[k]=v;
        end
    end
end

if reqType == 'POST' then
    ngx.req.read_body();
    local reqBody = ngx.req.get_body_data();
    local reqResult,reqErr = http_post(reqUrl,reqHeaders,reqBody,30000);
    ngx.status = reqResult.status;
    setResHeader(reqResult);
    if(reqResult.status==200) then
        --返回200 code码时直接将结果返回
        ngx.say(reqResult.body);
        return ;
    elseif(reqResult.status==302) then
        --返回302 重定向时 需要将重定向url 赋值到response 的header.Location中
        ngx.header.Location=reqResult.headers.location;
        return ;
    else
        --报错处理
        if reqErr == nil then
            reqErr="";
        end
        ngx.say(reqResult.status..":"..reqErr);
        return ;
    end
else
    local reqResult,reqErr = http_get(reqUrl,reqHeaders,30000);
    ngx.status = reqResult.status;
    setResHeader(reqResult);
    if(reqResult.status==200) then
        ngx.say(reqResult.body);
        return ;
    elseif(reqResult.status==302) then
        ngx.header.Location=reqResult.headers.location;
        return ;
    else
        if reqErr == nil then
            reqErr="";
        end
        ngx.say(reqResult.status..":"..reqErr);
        return ;
    end
end

四、nginx 引入lua脚本

server {
    listen          80;
    server_name     www.timer.com;
    access_log      /export/servers/nginx/logs/nginx_access.log realaddr;
    error_log       /export/Logs/nginx_errr.log warn;
	
    root /export/Instances/timer/runtime/;
  
    index index.html;
    charset utf-8;
	
    location / {
	  #default_type 'text/html';   返回HTML页面
      default_type 'application/json'; #返回Json文本
      charset utf-8;  
      lua_code_cache off;
      #加载引入lua脚本
      content_by_lua_file /export/Instances/timer/runtime/lua/gateway.lua;
    }
}

注:使用access_by_lua_file加载lua脚本会出现间接性404问题:https://blog.csdn.net/TimerBin/article/details/103850392
五、其他资料
resty-http帮助文档: https://github.com/ledgetech/lua-resty-http#request

猜你喜欢

转载自blog.csdn.net/TimerBin/article/details/103972968