nginx lua在不阻止请求的情况下进行外部http调用

时间:2017-04-11 06:01:28

标签: nginx lua

当某些情况发生时,我们需要从nginx将事件记录到我们的事件服务器。我知道我可以使用access_by_lua进行http调用。由于事件记录可能会失败或需要更长时间,因此我们不希望请求处理等待http操作完成。

如果我使用lua访问,则记录所需的时间将被添加到请求时间。

有没有办法在异步进程中启动事件日志记录进程,以便请求可以继续进行,而事件日志记录可以花费时间。

2 个答案:

答案 0 :(得分:0)

我不在nginx上试试。但在我的应用程序中,我使用单独的线程来执行所有IO并使用ZeroMQ库与它进行通信。 根据doc,您可以使用init_by_lua_block中的通信套接字创建/运行工作线程,然后在其他部分中使用它。但要做到这一点你应该记住,如果请求/秒总是大于写/秒,那么最终你可能会失去内存。使用ZeromMQ也很容易做出几个工作线程。当然,在这种情况下,工作线程无法访问nginx模块。 但你可以使用例如LuaSocket或Lua-cURL(最后一个可用于在异步模式下执行多个请求)。 单线程的基本场景。

local thread = function(actor)
  local msg, err while true do
    msg, err = actor:recvx()
    if not msg then break end
    print(msg)
  end
  print('Close thread: ', tostring(err))
end

local zthreads = require "lzmq.threads"
local ztimer   = require "lzmq.timer"
local actor    = zthreads.xactor(thread):start()

for i = 1, 10 do
  actor:send(string.format('message #%d', i))
  ztimer.sleep(1000)
end

答案 1 :(得分:0)

您可以在content_by_lua_ *中进行常规处理,并通过ngx.eof()

明确指定响应输出流的结束

因此,HTTP请求将毫不拖延地处理。

之后你可以做任何你想做的事情,例如使用cosocket API或ngx.location.capture()

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

以下是文档中的示例:

 location = /async {
     keepalive_timeout 0;
     content_by_lua_block {
         ngx.say("got the task!")
         ngx.eof()  -- well written HTTP clients will close the connection at this point
         -- access MySQL, PostgreSQL, Redis, Memcached, and etc here...
     }
 }