> 文章列表 > nginx中lua-redis使用

nginx中lua-redis使用

nginx中lua-redis使用

文章目录

  • lua-resty-redis二次封装
  • lua-redis-cmd封装shell命令行

ngx_lua开发往往需要与Redis做交互。以下有两种与redis的交互方式。

lua-resty-redis二次封装

使用OpenResty中的lua-resty-redis 这个模块操作 Redis。
对 lua-resty-redis进行了二次封装,封装了开箱即用的连接池,每次 Redis 使用完毕,自动释放 Redis 连接到连接池供其他请求复用。
封装了针对hash/set数据类型的操作方法。

redis-config.lua

local _M = {redis={ip="192.168.0.12",port="6379",database=1,timeout=10000,max_idle_time=60000,pool_size = 100,auth="xxx"}
}
return _M

redis-utils.lua

local _M = {}
local redis = require("resty.redis")
local red_config = require('redis-config')
local ip = red_config.redis['ip']
local port = red_config.redis['port']
local database = red_config.redis['database']
local auth = red_config.redis['auth']
local timeout = red_config.redis['timeout']
local max_idle_time = red_config.redis['max_idle_time']
local pool_size = red_config.redis['pool_size']
local unpack = unpack or table.unpackfunction _M.exec(func)local red = redis:new()red:set_timeout(timeout)local ok, err = red:connect(ip, port)if not ok thenngx.say("redis","Cannot connect, host: " .. ip .. ", port: " .. port)ngx.log(ngx.ERR, "redis","Cannot connect, host: " .. ip .. ", port: " .. port)return nil, errendlocal count, err = red:get_reused_times()if 0 == count thenok, err = red:auth(auth)if not ok thenngx.say("failed to auth: ", err)ngx.log(ngx.ERR,"failed to auth: ", err)returnendelseif err thenngx.say("failed to get reused times: ", err)ngx.log(ngx.ERR,"failed to get reused times: ", err)returnendngx.say("get reused times: ", count)ngx.log(ngx.WARN,"get reused times: ", count)red:select(database)local res, err = func(red)if res thenlocal ok, err1 = red:set_keepalive(max_idle_time, pool_size)if not ok thenred:close()endend return res, err
end--hash
function _M.hkeys(key, ...)local array={}for i = 1, select('#', ...) doarray[i]=select(i, ...)ngx.say(array[i])ngx.log(ngx.WARN,array[i])endlocal res, err = _M.exec(function(red)return red:hkeys(unpack(array))end)if not res then  return nilendif type(res) == "userdata" thenreturn nilendreturn res
endfunction _M.hset(key, ...)local array={}for i = 1, select('#', ...) doarray[i]=select(i, ...)ngx.say(array[i])ngx.log(ngx.WARN,array[i])endlocal res, err = _M.exec(function(red)--red:expire(key, expires)return red:hset(unpack(array))end)if not res thenreturn nilendif type(res) == "userdata" thenreturn nilendreturn res
endfunction _M.hget(key, ...)local array={}for i = 1, select('#', ...) doarray[i]=select(i, ...)ngx.say(array[i])ngx.log(ngx.WARN,array[i])endlocal res, err = _M.exec(function(red)return red:hget(unpack(array))end)if not res thenreturn nilendif type(res) == "userdata" thenreturn nilendreturn res
end--set
function _M.smembers(key, ...)local array={}for i = 1, select('#', ...) doarray[i]=select(i, ...)ngx.say(array[i])ngx.log(ngx.WARN,array[i])endlocal res, err = _M.exec(function(red)return red:smembers(unpack(array))end)if not res thenreturn nilendif type(res) == "userdata" thenreturn nilendreturn res
endfunction _M.sismember(key, ...)local array={}for i = 1, select('#', ...) doarray[i]=select(i, ...)ngx.say(array[i])ngx.log(ngx.WARN,array[i])endlocal res, err = _M.exec(function(red)return red:sismember(unpack(array))end)if not res thenreturn nilendif type(res) == "userdata" thenreturn nilendreturn res
endfunction _M.srem(key, ...)local array={}for i = 1, select('#', ...) doarray[i]=select(i, ...)ngx.say(array[i])ngx.log(ngx.WARN,array[i])endlocal res, err = _M.exec(function(red)return red:srem(unpack(array))end)if not res thenreturn nilendif type(res) == "userdata" thenreturn nilendreturn res
endfunction _M.sadd(key, ...)local array={}for i = 1, select('#', ...) doarray[i]=select(i, ...)ngx.say(array[i])ngx.log(ngx.WARN,array[i])endlocal res, err = _M.exec(function(red)return red:sadd(unpack(array))end)if not res thenreturn nilendif type(res) == "userdata" thenreturn nilendreturn res
endreturn _M

lua-redis-cmd封装shell命令行

由于在【init_by_lua_file】初始化全局变量阶段,lua-resty-redis还未被加载,因此需要通过封装shell命令行访问redis获得初始化数据。

redis-config.lua

local _M = {redis={ip="192.168.0.12",port="6379",database=1,timeout=10000,max_idle_time=60000,pool_size = 100,auth="xxx"}
}
return _M

redis-utils-cmd.lua

local _M = {}
local red_config = require('redis-config')
local ip = red_config.redis['ip']
local port = red_config.redis['port']
local database = red_config.redis['database']
local auth = red_config.redis['auth']
local timeout = red_config.redis['timeout']
local max_idle_time = red_config.redis['max_idle_time']
local pool_size = red_config.redis['pool_size']
local redis_connect = "redis-cli -h "..ip.." -p "..port.." -n "..database.."  -a '"..auth.."' --no-auth-warning"function _M.hkeys_hgets(key)local upstreams = {}--local cmd=redis_connect.." hkeys "..key.." | awk '{print $NF}' | awk -F '\\"' '{print $2}'"local cmd=redis_connect.." hkeys "..key.." | awk '{print $NF}'"local f = io.popen(cmd)--line = f:read("a")local line = f:read()while(line ~= nil and line ~= " ")doupstreams[line] = _M.hget(key,line)--print(line,upstreams[line])line = f:read()endf:close()return upstreams
endfunction _M.hget(key,field)--local cmd=redis_connect.." hget "..key.." "..field.." | awk -F '\\"' 'NR==1{print $2}'"local cmd=redis_connect.." hget "..key.." "..fieldlocal f = io.popen(cmd)local line = f:read()f:close()return line
endfunction _M.smembers(key)local _table = {}--local cmd=redis_connect.." smembers "..key.." | awk '{print $NF}' | awk -F '\\"' '{print $2}'"local cmd=redis_connect.." smembers "..key.." | awk '{print $NF}'"local f = io.popen(cmd)local line = f:read()while(line ~= nil and line ~= " ")do_table[line] = true--print(line,_table[line])line = f:read()endf:close()return _table
endreturn _M--redis = require("redis-utils-cmd")
--t = redis.smembers('usernames')
--for k,v in pairs(t)
--do
--    print(k,v)
--end