nginx+lua+redis实现高并发接口(一)

/ 浏览:373 次

接下来工作需要提供一个数据采集接口,公司有个旧系统使用nginx+lua将数据推送到redis,这正好是很久之前我思考过的一个方案,所以新接口依然使用这种方式,并将这一整套流程记录下来。

下面步骤以centos为例:

  1. 配置lua环境(官网下载) mkdir /opt/lua wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz -O /opt/lua/LuaJIT-2.0.5.tar.g tar -zxvf LuaJIT-2.0.5.tar.gz make PREFIX=/opt/lua/target make install PREFIX=/opt/lua/target

  2. 从nginx官网下载最新版本 wget http://nginx.org/download/nginx-1.15.4.tar.gz
  3. 下载lua和redis模块 wget https://github.com/openresty/lua-nginx-module/archive/v0.10.13.tar.gz -O lua-nginx-module_v0.10.13.tar.gz wget https://github.com/openresty/redis2-nginx-module/archive/v0.15.tar.gz -O redis2-nginx-module_v0.15.tar.gz wget https://github.com/simplresty/ngx_devel_kit/archive/v0.3.0.tar.gz -O ngx_devel_kit_v0.3.3.tar.gz 然后解压 tar -zxvf ....
  4. 配置lua环境(官网下载) mkdir /opt/lua wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz -O /opt/lua/LuaJIT-2.0.5.tar.g tar -zxvf LuaJIT-2.0.5.tar.gz make PREFIX=/opt/lua/target make install PREFIX=/opt/lua/target
  5. 配置nginx cd /opt/nginx/nginx-1.15.4 ./configure --prefix=/opt/nginx/target --add-module=/opt/nginx/module/ngx_devel_kit-0.3.0 --add-module=/opt/nginx/module/redis2-nginx-module-0.15 --add-module=/opt/nginx/module/lua-nginx-module-0.10.13

    5.1 到这一步出现 ngx_http_lua_module requires the Lua library.(ubuntu下应该不会) 通过yum安装lua开发包解决(yum install lua-devel)

  6. make install

到此安装结束~ 开始配置服务和上传代码

  1. 在nginx配置增加两个location(vim cong/nginx/conf)

    location /lua {
                lua_code_cache on;
                content_by_lua_file lua/dclog.lua;
        }
    location /redis {
                internal;
                redis2_query auth ****;
                redis2_query select 0;
                redis2_query rpush logQuene '$args';
                redis2_pass ****.com:6379;
    }
  2. 在lua目录下放置写好的lua代码(touch lua/dclog.lua)

    scp lua/dclog.lua root@***.com:/opt/nginx/target/lua
  3. 启动nginx测试:
nan@nan-AirBook:/opt/middleware/nginx/target$ curl -X GET -i 'http://yangdengnan.com/lua?a=1&b=2'
HTTP/1.1 200 OK

+OK
+OK
:1

nan@nan-AirBook:/opt/middleware/nginx/target$ curl -X POST -i 'http://yangdengnan.com/lua' --data '{
"a":"1"
,"b":"2"
}'

HTTP/1.1 200 OK

+OK
+OK
:2

nan@nan-AirBook:/opt/middleware/nginx/target$ curl -X PUT -i 'http://yangdengnan.com/lua?a=1&b=2'
curl: (52) Empty reply from server
nan@nan-AirBook:/opt/middleware/nginx/target$

上传的lua代码如下:

local function passToJson(ngArgs)
        local str =  "{";
        for k,v in pairs(ngArgs) do
                if (type(v) == 'table')
                        then
                                str = "" .. str .. "\"" .. tostring(k) .. "\":" .. passToJson(v) .. ",";
                                --str = "" .. str .. "\"" .. tostring(k) .. "\":" .. passToJson(v) .. ",";
                        else
                                --str = "" .. str .. "\"" ..tostring(k) .. "\":\"" .. tostring(v) .. "\",";
                                str = "" .. str .. "\"" ..tostring(k) .. "\":'" .. tostring(v) .. "',";
                        end
        end
        str = string.sub(str,1,-2) .. "}";
        return str;
end

local function passToText(ngArgs)
    for k,v in pairs(ngArgs) do
        return k;
    end
end

------------------ function end AND main start ------------------

local switch = setmetatable({
    ['GET'] = function()
    return passToJson(ngx.req.get_uri_args());
    end,
    ['POST'] = function()
    ngx.req.read_body();
    return passToText(ngx.req.get_post_args());
    end
},{
    __index = function(subTable,key)
        ngx.say("no support request Method : " .. key);
        ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR);
    end
});
local data = {};
data['args'] = switch[ngx.var.request_method]();
--data['header'] = ngx.req.get_headers();
local str = passToJson(data);
local res = ngx.location.capture("/redis", {args=str});
--ngx.say(passToJson(res));
local response = {};
if (res.status ~= 200 or  string.find(res.body,'ERR') or string.find(res.body,'err'))
    then
        response['code']=0;
        response['error']='' .. tostring(((string.gsub(res.body,'%s',''))));
    else
        response['code']=1;
    end
ngx.say(passToJson(response));

如果你想转载,请注明来源或者出处