HttpLuaModule create asynchronous subrequests
Guido Accardo
guido at motrixi.com
Wed Nov 12 20:20:35 UTC 2014
Hi,
With the help of HttpLuaModule I'm trying to duplicate every request
into two upstreams. Here is my configuration:
site.conf
---
upstream prod_upstream {
server 127.0.0.1:5000;
server 127.0.0.1:5001;
}
upstream dev_upstream {
server 127.0.0.1:6000;
}
server {
location /prod {
proxy_pass http://prod_upstream/;
}
location /dev {
proxy_pass http://dev_upstream/;
}
location / {
error_log "/tmp/error.log";
content_by_lua_file /etc/nginx/luas/duplicator.lua;
}
}
duplicator.lua
---
ngx.req.read_body()
local arguments = ngx.var.args
r1, r2 = ngx.location.capture_multi {
{ '/prod/', { args = arguments, share_all_vars = true } },
{ '/dev/', { args = arguments, share_all_vars = true } },
}
ngx.print(r1.body)
So far so good, all traffic destined to prod is being duplicated to dev and
ONLY prod response is forwarded the client.
>From the documentation here
http://wiki.nginx.org/HttpLuaModule#ngx.location.capture_multi :
" ... This function will not return until all the subrequests terminate ...
"
That is where my problem starts:
I'm working with a real time distributed system so the response time can't
be longer than 50ms. Dev is definitely slower so I can't wait for dev
response. Also Imagine if /dev is broken the timeout will take too much
time.
I'm thinking about making /dev calls in an asynchronous way if possible.
My second approach:
duplicator_v2.lua:
---
gx.req.read_body()
local arguments = ngx.var.args
r1 = ngx.location.capture('/prod/', { args = arguments, share_all_vars =
true })
ngx.print(r1.body)
r2 = ngx.location.capture('/dev/', { args = arguments, share_all_vars =
true })
>From the documentation of ngx.print:
" ... This is an asynchronous call and will return immediately without
waiting for all the data to be written into the system send buffer ..."
I was hopping that splitting the captures and using ngx.print before the
second call will do what I need, answer to the client and continue with
calling /dev but that doesn't happen, works exactly as the first approach.
My final tests was this ugly configuration:
duplicator_v2.lua:
---
gx.req.read_body()
local arguments = ngx.var.args
r1 = ngx.location.capture('/prod/', { args = arguments, share_all_vars =
true })
ngx.print(r1.body)
ngx.eof()
r2 = ngx.location.capture('/dev/', { args = arguments, share_all_vars =
true })
Here, prod response is sent immediately as I want and dev receives the
traffic but the connection is closed the I got a Broken Pipe (which makes
sense).
Is there a way to do capture calls in a asynchronous mode or to achieve
this in other way?
Thank you in advance,
--
---
Guido Accardo
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx/attachments/20141112/b5d159e7/attachment.html>
More information about the nginx
mailing list