前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >lua模块demo(redis,http,mysql,cjson,本地缓存)

lua模块demo(redis,http,mysql,cjson,本地缓存)

作者头像
老梁
发布2019-09-10 18:26:06
1.5K0
发布2019-09-10 18:26:06
举报

1. lua模块demo(redis,http,mysql,cjson,本地缓存)

1.1. 配置

  1. 在nginx.conf中设置lua_shared_dict my_cache 128m; 开启nginx本地缓存,放到http{} 层
  2. location配置
location /redis-get{
    resolver 8.8.8.8;
    default_type text/html;
    content_by_lua_file /usr/local/openresty/lua/redis-get.lua;
}
  1. 这里推荐个工具,使用notepad++,下载个插件NppFtp,效果如下图,可以直接对liunx上的文件进行编辑保存

1.2. http

  1. 远程调用可以使用该模块 https://github.com/ledgetech/lua-resty-http
  2. 把lib包里的两个文件复制到 /usr/local/openresty/lualib/resty
  3. 通过require("resty.http") 调用

1.3. mysql

  1. 连接工具
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

参考 https://www.cnblogs.com/zhuzi91/p/7879956.html

1.4. string工具

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. 整合redis+本地缓存

-- 自定义的字符串转换工具
local stringEx = require("stringExt")

-- 本地缓存
local local_cache = ngx.shared.my_cache

-- redis连接池,设置连接空闲时间
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

-- 读redis缓存
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请求参数
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调用工具,需要额外下载,地址: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参数不写可能导致报错
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

-- 测试调用结果
-- 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. 总结

  1. 本文记录了对http,mysql,redis,nginx本地缓存的基本使用方式,后续需要使用到该模块的需求可以直接参考修改本示例代码
  2. 对于实际的互联网需求,这里可以想象个基于这些模块的需求,优先读取ngnix本地缓存,过期时间较短,其次读取redis缓存,减少redis压力,进一步减少mysql读取压力
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-03-08 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. lua模块demo(redis,http,mysql,cjson,本地缓存)
    • 1.1. 配置
      • 1.2. http
        • 1.3. mysql
          • 1.4. string工具
            • 1.5. 整合redis+本地缓存
              • 1.6. 总结
              相关产品与服务
              云数据库 Redis
              腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档