Nginx lua makes external HTTP call without blocking request

We need to write an event to our event server from nginx when some condition happens. I understand that I could use access_by_lua to call http. Since logging events may fail or take longer, we don't want to request processing to wait for the http operation to complete.

If I use lua access, the amount of time it takes to register will be added to the request time.

Is there a way to start the event logging process in the async process so that the request can move on while the event log can take that time.

+3


source to share


2 answers


I have not tried this on nginx. But in my application, I use a separate thread to perform all I / O and communicate with it using the ZeroMQ library. According to the doc, you can create / start a worker thread with a communication socket in init_by_lua_block

and then use it in other parts. But to do this, you must remember that if request / sec is consistently greater than write / sec, then at the end you can exit memory. Also with ZeromMQ it is quite easy to do multiple worker threads. Of course, in this case, the worker thread does not have access to the nginx module. But you can use for example. LuaSocket or Lua-cURL (the latter can be used to make multiple requests asynchronously). Single-threaded main skeleton.



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

      

0


source


You can do normal processing in content_by_lua_ * and explicitly set the end of the response output stream to ngx.eof()

This way, the HTTP request will be processed without any delay.

After that you can do whatever you want using the comocket API or ngx.location.capture () like



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

Here's an example from the documentation:

 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...
     }
 }

      

0


source







All Articles