共计 20943 个字符,预计需要花费 53 分钟才能阅读完成。
之前在使用lua-resty-redis模块调用redis时没有是使用连接池的方式,所以每一次需要调用redis的请求都会新建TCP链接。每一次新建断开都是要进行TCP三次握手四次挥手,耗费资源且低效,所以为了复用TCP链接,我们可以使用redis的链接池。设定一个固定链接池,每次调用完redis后不释放链接,而是将其放置回池中供后续使用
未使用链接池时,在redis中monitor指令查看状态,可以看到每次请求都是来自不同TCP链接
[root@nginx-cluster ~]# redis-cli -h 192.168.44.170
192.168.44.170:6379>
192.168.44.170:6379> MONITOR
OK
1631893230.044659 [0 192.168.44.145:57232] "sismember" "block-ip-list" "192.168.44.145"
1631893241.606487 [0 192.168.44.145:57236] "sismember" "block-ip-list" "192.168.44.145"
1631893257.586227 [0 192.168.44.145:57240] "sismember" "block-ip-list" "192.168.44.145"
1631893261.755798 [0 192.168.44.145:57244] "sismember" "block-ip-list" "192.168.44.145"
lua-resty-redis模块链接池
set_keepalive
syntax: ok, err = red:set_keepalive(max_idle_timeout, pool_size)
In case of success, returns 1
. In case of errors, returns nil
with a string describing the error.
将之前的例子在结束调用时增加以下行即可
-- put it into the connection pool of size 100,
-- with 10 seconds max idle time
local ok, err = red:set_keepalive(10000, 100)
if not ok then
ngx.say("failed to set keepalive: ", err)
return
end
Only call this method in the place you would have called the
close
method instead. Calling this method will immediately turn the current redis object into theclosed
state. Any subsequent operations other thanconnect()
on the current object will return theclosed
error
注意:使用了red:set_keepalive()后,之后的逻辑中若需要再次redis操作,需要重新发起connect(),相当于该方法自动带closed方法,不需要再接closed方法!
所以博主之前的写法稍微调整下
[root@nginx-cluster lua]# cat ip_acl_redis3.lua
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000) -- 1 sec
local ok,err = red:connect("192.168.44.170",6379)
if not ok then
ngx.say("failed to connect: ",err)
return
end
ngx.log(ngx.INFO, " ok: ", ok, " type(ok): ", type(ok)," err: ", err)
--- 获取代理头部中透传的真实客户端地址
local headers=ngx.req.get_headers()
local ip = headers["X-REAL-IP"] or headers["X_FORWARDED_FOR"] or ngx.var.remote_addr
--- 判断ip是否set中的元素,若为真则返回为1
local res, err = red:sismember('block-ip-list', ip)
if 1 == res then
ngx.log(ngx.INFO, "client ip in block-ip-list: ", ip)
local ok, err = red:set_keepalive(60000, 1)
ngx.exit(ngx.HTTP_FORBIDDEN)
else
ngx.log(ngx.INFO, "client ip not in block-ip-list: ", ip)
local ok, err = red:set_keepalive(60000, 1)
end
if not ok then
ngx.say("failed to set keepalive: ", err)
return
end
此时测试下访问情况,,注意连接池是工作进程级的,博主这里四个worker,所以可以看到有四个链接复用
1631894073.340721 [0 192.168.44.145:56380] "sismember" "block-ip-list" "192.168.44.145"
1631894082.390888 [0 192.168.44.145:56384] "sismember" "block-ip-list" "192.168.44.145"
1631894083.322968 [0 192.168.44.145:56384] "sismember" "block-ip-list" "192.168.44.145"
1631894084.159351 [0 192.168.44.145:56384] "sismember" "block-ip-list" "192.168.44.145"
1631894084.983031 [0 192.168.44.145:56384] "sismember" "block-ip-list" "192.168.44.145"
1631894085.783324 [0 192.168.44.145:56394] "sismember" "block-ip-list" "192.168.44.145"
1631894086.602929 [0 192.168.44.145:56384] "sismember" "block-ip-list" "192.168.44.145"
1631894087.413118 [0 192.168.44.145:56400] "sismember" "block-ip-list" "192.168.44.145"
1631894088.166519 [0 192.168.44.145:56384] "sismember" "block-ip-list" "192.168.44.145"
1631894088.943466 [0 192.168.44.145:56394] "sismember" "block-ip-list" "192.168.44.145"
1631894102.485094 [0 192.168.44.145:56400] "sismember" "block-ip-list" "192.168.44.145"
1631894103.288621 [0 192.168.44.145:56384] "sismember" "block-ip-list" "192.168.44.145"
1631894104.132416 [0 192.168.44.145:56400] "sismember" "block-ip-list" "192.168.44.145"
1631894104.944679 [0 192.168.44.145:56384] "sismember" "block-ip-list" "192.168.44.145"
1631894105.750793 [0 192.168.44.145:56380] "sismember" "block-ip-list" "192.168.44.145"
此时博主的连接池依然是1,即每个worker进程一个keepalive一个redis connect,如下图监控所示(存在探测链接2个,加上突然增加的4个keepalive链接共6个)
当我未调整进程池连接数时,如果此时并发超过链接池时,不会阻碍请求,也就是当链接池不够时,而是直接新建连接,只有4个连接会keepalive
[root@nginx-cluster conf.d]# ab -c 20 -n 20 http://192.168.44.145:8086/greating
# 对应日志
1631897280.687690 [0 192.168.44.145:60980] "sismember" "block-ip-list" "192.168.44.145"
1631897280.690025 [0 192.168.44.145:60950] "sismember" "block-ip-list" "192.168.44.145"
1631897280.690047 [0 192.168.44.145:60980] "sismember" "block-ip-list" "192.168.44.145"
1631897280.691149 [0 192.168.44.145:60968] "sismember" "block-ip-list" "192.168.44.145"
1631897280.691709 [0 192.168.44.145:60952] "sismember" "block-ip-list" "192.168.44.145"
1631897280.692388 [0 192.168.44.145:32796] "sismember" "block-ip-list" "192.168.44.145"
1631897280.692410 [0 192.168.44.145:32798] "sismember" "block-ip-list" "192.168.44.145"
1631897280.692425 [0 192.168.44.145:32800] "sismember" "block-ip-list" "192.168.44.145"
1631897280.692446 [0 192.168.44.145:32802] "sismember" "block-ip-list" "192.168.44.145"
1631897280.692462 [0 192.168.44.145:32804] "sismember" "block-ip-list" "192.168.44.145"
1631897280.692476 [0 192.168.44.145:32806] "sismember" "block-ip-list" "192.168.44.145"
1631897280.692493 [0 192.168.44.145:32808] "sismember" "block-ip-list" "192.168.44.145"
1631897280.692506 [0 192.168.44.145:32810] "sismember" "block-ip-list" "192.168.44.145"
1631897280.696732 [0 192.168.44.145:32812] "sismember" "block-ip-list" "192.168.44.145"
1631897280.697052 [0 192.168.44.145:32814] "sismember" "block-ip-list" "192.168.44.145"
1631897280.697073 [0 192.168.44.145:32816] "sismember" "block-ip-list" "192.168.44.145"
1631897280.697721 [0 192.168.44.145:32818] "sismember" "block-ip-list" "192.168.44.145"
1631897280.699164 [0 192.168.44.145:32820] "sismember" "block-ip-list" "192.168.44.145"
1631897280.699267 [0 192.168.44.145:32822] "sismember" "block-ip-list" "192.168.44.145"
1631897280.699283 [0 192.168.44.145:32824] "sismember" "block-ip-list" "192.168.44.145"
1631897281.218788 [0 172.17.0.3:55382] "INFO" "ALL"
1631897282.220214 [0 172.17.0.3:55384] "INFO" "ALL"
1631897283.217621 [0 172.17.0.3:55386] "INFO" "ALL"
1631897284.220828 [0 172.17.0.3:55390] "INFO" "ALL"
1631897285.219402 [0 172.17.0.3:55394] "INFO" "ALL"
1631897286.220074 [0 172.17.0.3:55396] "INFO" "ALL"
1631897287.219696 [0 172.17.0.3:55398] "INFO" "ALL"
1631897288.217529 [0 172.17.0.3:55400] "INFO" "ALL"
1631897289.219929 [0 172.17.0.3:55402] "INFO" "ALL"
1631897289.473690 [0 192.168.44.145:60980] "sismember" "block-ip-list" "192.168.44.145"
1631897290.116170 [0 192.168.44.145:32796] "sismember" "block-ip-list" "192.168.44.145"
1631897290.217224 [0 172.17.0.3:55404] "INFO" "ALL"
1631897290.744571 [0 192.168.44.145:60980] "sismember" "block-ip-list" "192.168.44.145"
1631897291.218269 [0 172.17.0.3:55406] "INFO" "ALL"
1631897291.392570 [0 192.168.44.145:60980] "sismember" "block-ip-list" "192.168.44.145"
1631897292.038618 [0 192.168.44.145:60980] "sismember" "block-ip-list" "192.168.44.145"
1631897292.216908 [0 172.17.0.3:55408] "INFO" "ALL"
1631897292.649521 [0 192.168.44.145:60980] "sismember" "block-ip-list" "192.168.44.145"
1631897293.216575 [0 172.17.0.3:55414] "INFO" "ALL"
1631897293.384494 [0 192.168.44.145:60980] "sismember" "block-ip-list" "192.168.44.145"
1631897293.992413 [0 192.168.44.145:32796] "sismember" "block-ip-list" "192.168.44.145"
从上面日志输出来看,20并发超过pool_size=4设定,所以新建了连接,而后面用curl单次调用的链接则是pool中的链接。现在调整连接池为100后再测试,通过监控可以看到keepalive的链接为100
[root@nginx-cluster conf.d]# ab -c 100 -n 100 http://192.168.44.145:8086/greating
get_reused_times
syntax: times, err = red:get_reused_times()
This method returns the (successfully) reused times for the current connection. In case of error, it returns nil
and a string describing the error.
If the current connection does not come from the built-in connection pool, then this method always returns 0
, that is, the connection has never been reused (yet). If the connection comes from the connection pool, then the return value is always non-zero. So this method can also be used to determine if the current connection comes from the pool.
如果链接不是来自连接池,则返回0,若是则返回非0值。可以用来判断当前redis链接是否来自连接池。
微调下增加日志输出当前连接来源
[root@nginx-cluster lua]# cat ip_acl_redis3.lua
local redis = require "resty.redis"
local red = redis:new()
red:set_timeout(1000) -- 1 sec
local ok,err = red:connect("192.168.44.170",6379)
if not ok then
ngx.say("failed to connect: ",err)
return
end
ngx.log(ngx.INFO, " ok: ", ok, " type(ok): ", type(ok)," err: ", err)
--- 获取代理头部中透传的真实客户端地址
local headers=ngx.req.get_headers()
local ip = headers["X-REAL-IP"] or headers["X_FORWARDED_FOR"] or ngx.var.remote_addr
--- 判断ip是否set中的元素,若为真则返回为1
local res, err = red:sismember('block-ip-list', ip)
local times, terr = red:get_reused_times()
if times then
ngx.log(ngx.INFO, "times: ", times)
end
if 1 == res then
ngx.log(ngx.INFO, "client ip in block-ip-list: ", ip)
local ok, err = red:set_keepalive(60000, 1)
ngx.exit(ngx.HTTP_FORBIDDEN)
else
ngx.log(ngx.INFO, "client ip not in block-ip-list: ", ip)
local ok, err = red:set_keepalive(60000, 1)
end
if not ok then
ngx.say("failed to set keepalive: ", err)
return
end
对应日志
2021/09/18 18:06:07 [info] 31819#0: *55 [lua] ip_acl_redis3.lua:19: times: 2, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31819#0: *55 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31820#0: *51 [lua] ip_acl_redis3.lua:19: times: 1, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31820#0: *51 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31817#0: *48 [lua] ip_acl_redis3.lua:19: times: 1, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31819#0: *65 [lua] ip_acl_redis3.lua:19: times: 0, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31817#0: *48 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31819#0: *65 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31819#0: *58 [lua] ip_acl_redis3.lua:19: times: 0, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31819#0: *58 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31817#0: *64 [lua] ip_acl_redis3.lua:19: times: 0, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31817#0: *64 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31817#0: *61 [lua] ip_acl_redis3.lua:19: times: 0, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31817#0: *61 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31820#0: *66 [lua] ip_acl_redis3.lua:19: times: 0, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31820#0: *66 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31817#0: *57 [lua] ip_acl_redis3.lua:19: times: 0, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31817#0: *57 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31817#0: *50 [lua] ip_acl_redis3.lua:19: times: 0, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31817#0: *50 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31820#0: *63 [lua] ip_acl_redis3.lua:19: times: 0, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31820#0: *63 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31817#0: *49 [lua] ip_acl_redis3.lua:19: times: 0, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31817#0: *49 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31820#0: *62 [lua] ip_acl_redis3.lua:19: times: 0, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31820#0: *62 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31820#0: *60 [lua] ip_acl_redis3.lua:19: times: 0, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31820#0: *60 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31820#0: *59 [lua] ip_acl_redis3.lua:19: times: 0, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31820#0: *59 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31820#0: *54 [lua] ip_acl_redis3.lua:19: times: 0, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31820#0: *54 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31818#0: *52 [lua] ip_acl_redis3.lua:19: times: 1, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31818#0: *52 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31818#0: *56 [lua] ip_acl_redis3.lua:19: times: 0, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31818#0: *56 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31818#0: *53 [lua] ip_acl_redis3.lua:19: times: 0, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31818#0: *53 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.0", host: "192.168.44.145:8086"
2021/09/18 18:06:07 [info] 31817#0: *67 client closed connection while waiting for request, client: 192.168.44.145, server: 0.0.0.0:8086
2021/09/18 18:06:59 [info] 31819#0: *83 [lua] ip_acl_redis3.lua:9: ok: 1 type(ok): number err: nil, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.1", host: "192.168.44.145:8086"
2021/09/18 18:06:59 [info] 31819#0: *83 [lua] ip_acl_redis3.lua:19: times: 1, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.1", host: "192.168.44.145:8086"
2021/09/18 18:06:59 [info] 31819#0: *83 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.1", host: "192.168.44.145:8086"
2021/09/18 18:06:59 [info] 31819#0: *83 client 192.168.44.145 closed keepalive connection
2021/09/18 18:07:07 [info] 31818#0: *84 [lua] ip_acl_redis3.lua:9: ok: 1 type(ok): number err: nil, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.1", host: "192.168.44.145:8086"
2021/09/18 18:07:07 [info] 31818#0: *84 [lua] ip_acl_redis3.lua:19: times: 1, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.1", host: "192.168.44.145:8086"
2021/09/18 18:07:07 [info] 31818#0: *84 [lua] ip_acl_redis3.lua:26: client ip not in block-ip-list: 192.168.44.145, client: 192.168.44.145, server: , request: "GET /sayHello HTTP/1.1", host: "192.168.44.145:8086"
2021/09/18 18:07:07 [info] 31818#0: *84 client 192.168.44.145 closed keepalive connection
openresty对原redis模块二次封装
网上有一个很不错的封装,对比我之前写的,算了不比了 ε(┬┬﹏┬┬)3
[root@nginx-cluster lua]# cat cat comm/redis_iresty.lua
local redis_c = require "resty.redis"
local ok, new_tab = pcall(require, "table.new")
if not ok or type(new_tab) ~= "function" then
new_tab = function (narr, nrec) return {} end
end
local _M = new_tab(0, 155)
_M._VERSION = '0.01'
local commands = {
"append", "auth", "bgrewriteaof",
"bgsave", "bitcount", "bitop",
"blpop", "brpop",
"brpoplpush", "client", "config",
"dbsize",
"debug", "decr", "decrby",
"del", "discard", "dump",
"echo",
"eval", "exec", "exists",
"expire", "expireat", "flushall",
"flushdb", "get", "getbit",
"getrange", "getset", "hdel",
"hexists", "hget", "hgetall",
"hincrby", "hincrbyfloat", "hkeys",
"hlen",
"hmget", "hmset", "hscan",
"hset",
"hsetnx", "hvals", "incr",
"incrby", "incrbyfloat", "info",
"keys",
"lastsave", "lindex", "linsert",
"llen", "lpop", "lpush",
"lpushx", "lrange", "lrem",
"lset", "ltrim", "mget",
"migrate",
"monitor", "move", "mset",
"msetnx", "multi", "object",
"persist", "pexpire", "pexpireat",
"ping", "psetex", "psubscribe",
"pttl",
"publish", --[[ "punsubscribe", ]] "pubsub",
"quit",
"randomkey", "rename", "renamenx",
"restore",
"rpop", "rpoplpush", "rpush",
"rpushx", "sadd", "save",
"scan", "scard", "script",
"sdiff", "sdiffstore",
"select", "set", "setbit",
"setex", "setnx", "setrange",
"shutdown", "sinter", "sinterstore",
"sismember", "slaveof", "slowlog",
"smembers", "smove", "sort",
"spop", "srandmember", "srem",
"sscan",
"strlen", --[[ "subscribe", ]] "sunion",
"sunionstore", "sync", "time",
"ttl",
"type", --[[ "unsubscribe", ]] "unwatch",
"watch", "zadd", "zcard",
"zcount", "zincrby", "zinterstore",
"zrange", "zrangebyscore", "zrank",
"zrem", "zremrangebyrank", "zremrangebyscore",
"zrevrange", "zrevrangebyscore", "zrevrank",
"zscan",
"zscore", "zunionstore", "evalsha"
}
local mt = { __index = _M }
local function 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
function _M.connect_mod(self)
local redis, err = redis_c:new()
if not redis or err then
return nil, err
end
redis:set_timeout(self.timeout)
local ok, err = redis:connect(self.host, self.port)
if not ok or err then
return nil, err
end
if self.password then
local times, err = redis:get_reused_times()
if times == 0 then
local ok, err = redis:auth(self.password)
if not ok or err then
return nil, err
end
elseif err then
return nil, err
end
end
return redis, nil
end
function _M.set_keepalive_mod(self, redis)
return redis:set_keepalive(self.keepalive, self.pool_size)
end
function _M.init_pipeline(self)
self._reqs = {}
end
function _M.commit_pipeline(self)
local reqs = self._reqs
if reqs == nil or #reqs == 0 then
return {}, 'no pipeline'
else
self._reqs = nil
end
local redis, err = self:connect_mod()
if not redis or err then
return {}, err
end
redis:init_pipeline()
for _, v in ipairs(reqs) do
local method = redis[v[1]]
table.remove(v, 1)
method(redis, unpack(v))
end
local results, err = redis:commit_pipeline()
if not results or err then
return {}, err
end
if is_redis_null(results) then
results = {}
end
local ok, err = self:set_keepalive_mod(redis)
if not ok or err then
return {}, err
end
for k, v in ipairs(results) do
if is_redis_null(v) then
results[k] = nil
end
end
return results, nil
end
function _M.subscribe(self, channel)
local redis, err = self:connect_mod()
if not redis or err then
return {}, err
end
local res, err = redis:subscribe(channel)
if not res or err then
return nil, err
end
local function do_read_func(do_read)
if do_read == nil or do_read == true then
local res, err = redis:read_reply()
if not res or err then
return nil, err
end
return res
end
redis:unsubscribe(channel)
self.set_keepalive_mod(redis)
return
end
return do_read_func
end
local function do_command(self, cmd, ...)
if self._reqs then
self._reqs:insert({cmd, ...})
return
end
local redis, err = self:connect_mod()
if not redis or err then
return {}, err
end
local method = redis[cmd]
local result, err = method(redis, ...)
if not result or err then
return nil, err
end
if is_redis_null(result) then
result = nil
end
local ok, err = self:set_keepalive_mod(redis)
if not ok or err then
return nil, err
end
return result, nil
end
function _M.new(self, opts)
opts.host = opts.host or '127.0.0.1'
opts.port = opts.port or 6379
opts.db = opts.db or 0
opts.password = opts.password or nil
opts.timeout = opts.timeout or 1000
opts.keepalive = opts.keepalive or 60000
opts.pool_size = opts.pool_size or 100
opts._reqs = nil
for i = 1, #commands do
local cmd = commands[i]
_M[cmd] =
function (self, ...)
return do_command(self, cmd, ...)
end
end
return setmetatable(opts, mt)
end
return _M
查看上面封装的模块中的function _M.new(self, opts)
:
[root@nginx-cluster lua]# cat ip_acl_redis4.lua
local redis = require "comm.redis_iresty"
local opts = {
host = "192.168.44.170",
port = "6379",
db = 0,
keepalive = 60000,
pool_size = 200,
}
local red = redis:new(opts)
--- 获取代理头部中透传的真实客户端地址
local headers=ngx.req.get_headers()
local ip = headers["X-REAL-IP"] or headers["X_FORWARDED_FOR"] or ngx.var.remote_addr
--- 判断ip是否set中的元素,若为真则返回为1
local res, err = red:sismember('block-ip-list', ip)
if 1 == res then
ngx.log(ngx.INFO, "client ip in block-ip-list: ", ip)
ngx.exit(ngx.HTTP_FORBIDDEN)
else
ngx.log(ngx.INFO, "client ip not in block-ip-list: ", ip)
end
对应的location
location /sayHello {
access_by_lua_file lua/ip_acl_redis3.lua;
content_by_lua_block {
ngx.say("Allow Operating")
ngx.exit(ngx.OK)
}
}
location /greating {
access_by_lua_file lua/ip_acl_redis4.lua;
content_by_lua_block {
ngx.say("Allow Operating")
ngx.exit(ngx.OK)
}
}