openResty的Redis模块踩坑记录
OpenResty提供了操作Redis的模块,我们只要引入该模块就能直接使用。说是这样说,但是实践起来好像并不太顺利。
1.设置了密码的redis,lua业务逻辑中需要添加身份认证代码
网上很多资料、文章似乎都是没有设置redis密码,说来也奇怪,哈哈!如果你的redis设置了密码,而lua业务逻辑中却没有加身份认证代码,就会报错。
35200#0: *466 [lua] common.lua:39: read_redis(): Getting key is failed!NOAUTH Authentication required.
2.redis对象的共享问题
这是99%的人都会犯的错误。受Java语言编程的影响,为了更好的复用resty.redis对象,自然而然的会将resty.redis对象的初始化放在lua模块级的变量中供多个请求共享。比如像下面common.lua文件这样:
-
local redis = require("resty.redis")
-
local red = redis:new()
-
red:set_timeouts(1000,1000,1000)
-
-
local function read_redis(ip,port,password,key)
-
-
local ok,err = red:connect(ip,port)
-
if not ok then
-
ngx.log(ngx.ERR,"Connecting Redis is failed!",err,",key = ",key)
-
return nil
-
end
-
-
local res,err = red:auth(password)
-
if not res then
-
ngx.log(ngx.ERR,"Authentication is failed!",err);
-
return nil
-
end
-
-
local resp,err = red:get(key)
-
if not resp then
-
ngx.log(ngx.ERR,"Getting key is failed!",err,",key = ",key)
-
end
-
-
if resp==ngx.null then
-
resp = nil
-
ngx.log(ngx.ERR, "Redis value is null, key = ", key)
-
end
-
-
release_redis(red)
-
return resp
-
end
common.lua是封装公共函数的lua模块文件,此时的resty.redis对象会被所有调用read_redis函数的请求所共享。当出现大量请求并发的情况,会有非常多的redis调用失败,而在后台出现大量的bad request错误,导致openResty服务不可用。
35306#0: *504 lua entry thread aborted: runtime error: /usr/local/openresty/lualib/common.lua:30: bad request
官方文档已经明确指出,我们应该始终在函数的局部变量,或ngx.ctx table中初始化resty.redis对象,这些地方对每个请求都有自己的数据副本。
关于resty.redis对象初始化的描述.png
正确的做法是在函数中初始化resty.redis对象。这里的例子中指的是read_redis函数。
-
local redis = require("resty.redis")
-
-
local function read_redis(ip,port,password,key)
-
local red = redis:new()
-
red:set_timeouts(1000,1000,1000)
-
local ok,err = red:connect(ip,port)
-
if not ok then
-
ngx.log(ngx.ERR,"Connecting Redis is failed!",err,",key = ",key)
-
return nil
-
end
-
-
local res,err = red:auth(password)
-
if not res then
-
ngx.log(ngx.ERR,"Authentication is failed!",err);
-
return nil
-
end
-
-
local resp,err = red:get(key)
-
if not resp then
-
ngx.log(ngx.ERR,"Getting key is failed!",err,",key = ",key)
-
end
-
-
if resp==ngx.null then
-
resp = nil
-
ngx.log(ngx.ERR, "Redis value is null, key = ", key)
-
end
-
-
release_redis(red)
-
return resp
-
end
3.注意lua-resty-redis的版本
由于小编的上述代码中使用了set_timeouts函数,导致后台一直报错。
35829#0: *523 attempt to send data on a closed socket: u:0000000000000000, c:0000000000000000,
查阅了很多资料,最终发现set_timeouts函数是V0.28版本才加进来的。要想查看自己的lua-resty-redis的版本,可以打开lualib下的redis.lua文件查看,具体路径:
/usr/local/openresty/lualib/resty/redis.lua
你将会看到它的版本号。
lua-resty-redis的版本.png
解决方案:用set_timeout函数替代set_timeouts函数,即可解决。
red:set_timeout(1000)
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhfkkifj
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13