利用 Lua 的函數式編程簡化 lua-resty-redis 的使用
在利用 OpenResty 編寫高性能服務的時候,很有可能會使用到 Redis。在 OpenResty 中,我們通常使用 lua-resty-redis 這個模塊操作 Redis。
在 lua-resty-redis 的 示例 中,我們可以總結出以下幾個步驟:
-
導入 resty.redis 模塊
-
實例化 redis 對象:
local red = redis:new()
red:set_timeout(1000)
-
連接到服務器:
local ok, err = red:connect("127.0.0.1", 6379)
-
操作 Redis
-
將連接添加到連接池中
local ok, err = red:set_keepalive(1000, 100)
以上的幾個步驟是標準的使用方式,我們需要在每個使用的地方重復上面的幾個步驟。不知不覺,Lua 代碼會變的龐大起來。
通過上面的步驟,我們不難發現: 除了 Redis 操作不一樣,從實例化 Redis 到最后的連接資源管理都是一樣的。這時候,我們就可以使用通用的處理流去標準化它了!
在OpenResty最佳實踐中有章節介紹了對 lua-resty-redis 的第二次簡化封裝跟需要注意的事項。但是,我還是利用了 Lua 支持函數式編程的特性做了一個更加簡化的版本:
local redis = require "resty/redis"
local log = ngx.log
local ERR = ngx.ERR
local setmetatable = setmetatable
local _M = {
_VERSION = "1.0.0",
_AUTHOR = "Andy Ai"
}
local mt = { __index = _M }
local function errlog(...)
log(ERR, "Redis: ", ...)
end
function _M.exec(self, func)
local red = redis:new()
red:set_timeout(self.timeout)
local ok, err = red:connect(self.host, self.port)
if not ok then
errlog("Cannot connect, host: " .. self.host .. ", port: " .. self.port)
return nil, err
end
red:select(self.database)
local res, err = func(red)
if res then
local ok, err = red:set_keepalive(self.max_idle_time, self.pool_size)
if not ok then
red:close()
end
end
return res, err
end
function _M.new(opts)
local config = opts or {}
local self = {
host = config.host or "127.0.0.1",
port = config.port or 6379,
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
}
return setmetatable(self, mt)
end
return _M
從上面的代碼中可以看出:
我們將 Redis 的操作看成一個函數,在這個函數執行之前進行實例化跟連接;在函數執行之后進行連接資源的管理。
而,在實際的使用過程中也變得非常簡單:
local redis = require("resty.rediscli")
local red = redis.new({host = "127.0.0.1"})
local res, err = red:exec(
function(red)
return red:get("123456")
end
)
使用 Redis 的 Pipeline 也同樣很簡單:
red:exec(
function(red)
red:init_pipeline()
red:set(key, value)
red:expire(key, expires)
return red:commit_pipeline()
end
)
怎么樣? 我們使用 Lua 支持函數編程的特性恰到好處地將代碼很好地簡化了。這樣,不管是我們在實現邏輯,還是在維護邏輯都可以把精力更多地放在業務實現上,而不是處理這些瑣碎資源管理。
上面的代碼可以在 GitHub 上獲取: lua-resty-utils 。另外,不需要擔心它的穩定性!它已經被使用在 GrowingIO 的幾個非常重要的服務上!
來自:https://segmentfault.com/a/1190000007207616
本文由用戶 VerleneFass 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!