美文网首页
openResty的Redis模块踩坑记录

openResty的Redis模块踩坑记录

作者: 南湘嘉荣 | 来源:发表于2023-07-10 20:15 被阅读0次

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)

相关文章

  • Spring Redis踩坑记录

    现开发的项目中,某接口需要频获取同一个实体,如果每次都查数据库的话,性能消耗太大,于是决定使用redis做缓存。R...

  • Mac搭建openresty的坑

    Mac搭建openresty的坑 openresty网站:http://openresty.org/cn/inst...

  • 迁Aliyun Redis踩坑之路 - 实践总结

    背景: 从自建 redis(CacheCloud)到迁移到 aliyun redis 1. 踩“坑”一 问题: ...

  • 2020-10-19随笔 踩坑0传值

    踩坑:当值传入0时,if条件判断时候会自己转换,记录踩坑。

  • Weex入门踩坑记录

    Weex入门踩坑记录

  • Redis踩坑

    RDB备份 redis默认的持久化方式就是RDB,还有一种是AOF,默认是关闭的。 RDB的配置 备份的时间周期设...

  • PsRobot的使用流程 | 小麦篇

    ⭐⭐⭐本文记录我使用PsRobot的psRobot_tar模块识别靶基因的过程。踩了不少坑,供实验室师弟师妹们借鉴...

  • 日常bug记录

    想记录日常碰到的bug,坑踩多了,以后应该碰到坑就比较容易处理或者会少踩坑,后面会慢慢记录bug,截图bug以及最...

  • 没事请多踩踩坑!

    人生事不尽意,别人挖坑我踩坑。 请在这里留下你的踩坑记录,让别人少入坑。

  • Flutter 开发记录

    Flutter 开发踩坑记录(干货总结)

网友评论

      本文标题:openResty的Redis模块踩坑记录

      本文链接:https://www.haomeiwen.com/subject/hkzeudtx.html