特性
- 使用連接池
- 連接只需要一次認證
項目源碼
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...