博客 / 詳情

返回

openresty redis工具類lua-resty-redis封裝

特性

  • 使用連接池
  • 連接只需要一次認證

項目源碼

https://github.com/helloJiu/o...

安裝

opm install openresty/lua-resty-redis

代碼 redis.lua

-- redis客户端 
local redis = require("resty/redis")
local config = {
    host = "127.0.0.1",
    port = 6379,
    password = "",
    db_index = 0,
    max_idle_time = 30000,
    database = 0,
    pool_size = 100,
    timeout = 5000,
}

local _M = {}

function _M.new()
    local instance = {
        host = config.host or "127.0.0.1",
        port = config.port or 6379,
        password = config.password or "",
        timeout = config.timeout or 5000,
        database = config.database or 0,
        max_idle_time = config.max_idle_time or 60000,
        pool_size = config.pool_size or 100
    }
    setmetatable(instance, {__index = _M})
    return instance
end

function _M:exec(func)
    local red = redis:new()
    -- 為後續操作設置超時(以毫秒為單位)保護,包括connect方法。
    red:set_timeout(self.timeout)

    -- 建立連接
    local ok, err = red:connect(self.host, self.port)
    if not ok or err ~= nil then
        ngx.log(ngx.ERR, "redis: ", "connect error, host: " .. self.host .. ", port: " .. self.port, err)
        return nil, err
    end

    if self.password ~= "" then
        -- 如果連接來自於連接池中,get_reused_times() 永遠返回一個非零的值
        -- 只有新的連接才會進行授權
        local count = red:get_reused_times()
        if count == 0 then
            ok, err = red:auth(self.password)
            if not ok or err ~= nil then
                ngx.log(ngx.ERR, "redis: ", "auth error, host: " .. self.host .. ", port: " .. self.port, err)
                red:close()
                return nil, err
            end
        end
    end

    if self.database ~= 0 then
        red:select(self.database)
    end

    -- 執行業務邏輯
    local res, err = func(red)
    -- print(res, ', ', type(res), ', ', err, ', ', type(err))
    if res == nil or err ~= nil then
        -- 表示獲取數據錯誤, 不講連接放回連接池
        ngx.log(ngx.ERR, "redis: ", "exec command error" .. self.host .. ", port: " .. self.port, err)
        red:close()
        return nil, err
    end
    -- 將連接放回連接池
    red:set_keepalive(self.max_idle_time, self.pool_size)
    -- 轉換結果
    if self:is_redis_null(res) then
        res = nil
    end

    return res, err
end

function _M:is_redis_null( res )
    if type(res) == "table" then
        for k,v in pairs(res) do
            if v ~= ngx.null then
                return false
            end
        end
        return true
    elseif res == ngx.null then
        return true
    elseif res == nil then
        return true
    end

    return false
end

return _M

實際使用

local redis = require("redis")
local red = redis.new()
local v, err = red:exec(function(red)
    return red:get("wechat:login_key")
end)

-- print(v, type(v), err, type(err))
if not v then
    -- 處理key不存在情況
end
-- 處理存在情況

參考文章

  • https://moonbingbing.gitbooks...
  • https://segmentfault.com/a/11...
  • https://github.com/openresty/...
  • https://xiaorui.cc/archives/4784
  • https://cloud.tencent.com/dev...
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.