为什么 resty.redis 不能与 ngx.timer 一起使用?

why doesn't resty.redis work with the ngx.timer?

我已经问过 here,但我想我也会 post:

鉴于此代码:

local redis = require('resty.redis')

local client = redis:new()
client:connect(host,port)
ngx.thread.spawn(function()
  ngx.say(ngx.time(),' ',#client:keys('*'))
end)
ngx.timer.at(2,function()
  ngx.say(ngx.time(),' ',#client:keys('*'))
end)

我收到这个错误:

---urhcdhw2pqoz---
1611628086 5
2021/01/26 10:28:08 [error] 4902#24159: *4 lua entry thread aborted: runtime error: ...local/Cellar/openresty/1.19.3.1_1/lualib/resty/redis.lua:349: bad request
stack traceback:
coroutine 0:
    [C]: in function 'send'
    ...local/Cellar/openresty/1.19.3.1_1/lualib/resty/redis.lua:349: in function 'keys'
    ./src/main.lua:20: in function <./src/main.lua:19>, context: ngx.timer

所以线程似乎可以与 Redis 一起工作,但计时器不能。这是为什么?

您的代码中有两个错误。

  1. 无法在 Lua 处理程序之间传递 cosocket 对象(我添加的重点):

    The cosocket object created by this API function has exactly the same lifetime as the Lua handler creating it. So never pass the cosocket object to any other Lua handler (including ngx.timer callback functions) and never share the cosocket object between different Nginx requests.

    https://github.com/openresty/lua-nginx-module#ngxsockettcp

    在你的例子中,对 cosocket 对象的引用存储在 client table (client._sock).

  2. ngx.print/ngx.sayngx.timer.* 上下文中不可用。

    https://github.com/openresty/lua-nginx-module#ngxsay(检查 上下文: 部分)。

    您可以改用 ngx.log(它写入 nginx 日志,在 nginx.conf 中设置 error_log stderr debug; 以将日志打印到 stderr)。

以下代码按预期工作:

ngx.timer.at(2, function()
  local client = redis:new()
  client:connect('127.0.0.1' ,6379)
  ngx.log(ngx.DEBUG, #client:keys('*'))
end)