lua module demo (redis, http, mysql, cjson, local cache)

Keywords: Java Redis MySQL JSON Nginx

1. lua module demo (redis, http, mysql, cjson, local cache)

1.1. configuration

  1. Set lua_shared_dict my_cache 128m in nginx.conf; open nginx local cache and put it in http {} layer
  2. location configuration
location /redis-get{
    resolver 8.8.8.8;
    default_type text/html;
    content_by_lua_file /usr/local/openresty/lua/redis-get.lua;
}
  1. Here we recommend a tool to download a plug-in NppFtp using notepad++. The effect is as follows. You can edit and save the files on liunx directly.

1.2. http

  1. Remote calls can use this module https://github.com/ledgetech/lua-resty-http
  2. Copy the two files in the lib package to / usr/local/openresty/lualib/resty
  3. Called by require("resty.http")

1.3. mysql

  1. Connection tool
local connectMysqlUtil = {}

local mysql = require "resty.mysql"
-- connect to mysql;
function connectMysqlUtil.connect()
    local db, err = mysql:new()
    if not db then
        return false
    end
    db:set_timeout(1000)
    
    local ok, err, errno, sqlstate = db:connect{
        host = "127.0.0.1",
        port = 8083,
        database = "test",
        user = "dev",
        password = "1234",
        max_packet_size = 1024 * 1024 }
    
    if not ok then
        ngx.say("connect mysql failed")
        return false
    end
    return db
end

return connectMysqlUtil

Reference resources https://www.cnblogs.com/zhuzi91/p/7879956.html

1.4. string tool

local stringEx = {}

function stringEx.ToStringEx(value)
    if type(value)=='table' then
       return stringEx.TableToStr(value)
    elseif type(value)=='string' then
        return "\'"..value.."\'"
    else
       return tostring(value)
    end
end

function stringEx.TableToStr(t)
    if t == nil then return "" end
    local retstr= "{"

    local i = 1
    for key,value in pairs(t) do
        local signal = ","
        if i==1 then
          signal = ""
        end

        if key == i then
            retstr = retstr..signal..stringEx.ToStringEx(value)
        else
            if type(key)=='number' or type(key) == 'string' then
                retstr = retstr..signal..'['..stringEx.ToStringEx(key).."]="..stringEx.ToStringEx(value)
            else
                if type(key)=='userdata' then
                    retstr = retstr..signal.."*s"..stringEx.TableToStr(getmetatable(key)).."*e".."="..stringEx.ToStringEx(value)
                else
                    retstr = retstr..signal..key.."="..stringEx.ToStringEx(value)
                end
            end
        end

        i = i+1
    end

     retstr = retstr.."}"
     return retstr
end

function stringEx.StrToTable(str)
    if str == nil or type(str) ~= "string" then
        return
    end
    
    return loadstring("return " .. str)()
end

return stringEx

1.5. Integrate redis + local cache

-- Custom String Conversion Tool
local stringEx = require("stringExt")

-- Local cache
local local_cache = ngx.shared.my_cache

-- redis Connection pool, setting connection idle time
local function close_redis(red)
    if not red then
        return
    end
    local pool_max_idle_time = 10000
    local pool_size = 100
    local ok,err = red:set_keepalive(pool_max_idle_time,pool_size)
    if not ok then
        ngx.say("set keepalive fail ",err)
    end
end

-- read redis cache
local function read_redis(key)
    local redis = require("resty.redis")
    local red = redis.new();
    local ok,err = red:connect("127.0.0.1",8084)
    if not ok then 
        ngx.say("connect fail ",err)
        return close_redis(red)
    end
    red:set_timeout(1000)

    local count,err = red:get_reused_times()
    if 0==count then
        ok,err = red:auth("123456")
        if not ok then
            ngx.say("auth fail ",err)
            return close_redis(red)
        end
    elseif err then
        ngx.say("fail to get reused times")
        return close_redis(red)
    end

    local res,err = red:get(key)
    if not res then
        ngx.say("get msg fail ",err)
        return close_redis(red)
    elseif res then
        ngx.say(" set expire 10000 ")
        red:expire(key,10)
    end
    local_cache:set(key,res,5)
    ngx.say("read from redis ")
    ngx.say(res)
    close_redis(red)
end

-- http Request parameters
local args = ngx.req.get_uri_args()
local key = args["key"]
if not key then 
    ngx.say("key must be exist")
    return
end

local keyCache = local_cache:get(key)
if not keyCache then
    local res = read_redis(key)
    if not res then
        ngx.say("redis is null")
    end
else
    ngx.say("read from localCache ")
    ngx.say(keyCache)
end

-- http Call tool, need additional download, address: https://github.com/ledgetech/lua-resty-http: https://blog.csdn.net/xiejunna/article/details/53445342
local http = require("resty.http")
local httpc = http.new();
if not httpc then 
    ngx.say("\n\r httpc new fail")
end
httpc:set_timeout(8000)
-- keepalive Failure to write parameters may result in error reporting
local res,err = httpc:request_uri("http://www.xxx.com",{
    method="POST",
    path="/xxx/rpc.api",
    body = 'a=1&b=2',
    headers = {
          ["Content-Type"] = "application/x-www-form-urlencoded",
        },
    keepalive_timeout = 60,
    keepalive_pool = 10
})
if not res then
    ngx.say("httpc call fail ")
    return
end
local cjson = require("cjson")
local json = cjson.new()
if not json then
    ngx.say("json is null")
    return
end

-- Test call results
-- ngx.say(stringEx.TableToStr(res))
-- ngx.say(stringEx.ToStringEx(json.decode(res["body"])))
-- ngx.say(type(json.decode(res["body"])))
-- ngx.say(stringEx.ToStringEx(json.decode(res["body"])["header"]["request_seq"]))
-- ngx.say(type(json.decode(res["body"])["header"]))
-- ngx.say(type(json.decode(res["body"])["header"]["request_seq"]))

local connectMysqlUtil = require("connectMysqlUtil")
local db = connectMysqlUtil.connect()
if not db then
    ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
    return
end

local res,err,errcode,sqlstate = db:query("select * from t_uls_order_info where order_id='20190119232946000023'",10)
if not res then
    ngx.say("bad request: ",err,":",errcode,": ",sqlstate,".")
    return
end

ngx.say("result:",json.encode(res))

1.6. summary

  1. This paper records the basic usage of http, mysql, redis, nginx local caches. The following requirements for using this module can be directly referred to modify the sample code.
  2. For the actual demand of the Internet, we can imagine a demand based on these modules. First, read the ngnix local cache, which has a short expiration time. Second, read the redis cache to reduce the redis pressure, and further reduce the mysql reading pressure.

Posted by webosb on Fri, 08 Mar 2019 00:48:25 -0800