当某些情况发生时,我们需要从nginx将事件记录到我们的事件服务器。我知道我可以使用access_by_lua进行http调用。由于事件记录可能会失败或需要更长时间,因此我们不希望请求处理等待http操作完成。
如果我使用lua访问,则记录所需的时间将被添加到请求时间。
有没有办法在异步进程中启动事件日志记录进程,以便请求可以继续进行,而事件日志记录可以花费时间。
答案 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...
}
}