Async Post call by Lua httpresty (Fire and Forget to outside server) | Non-blocking

631 views
Skip to first unread message

Sunny GUPTA

unread,
Feb 10, 2016, 6:15:19 AM2/10/16
to openresty-en
Hi All,


I am trying to sent a packet to remote server. I want a method to HTTP POST in asynchronous with non-blocking effect (fire and forget) and dont want any response feed,
I am intercepting an incoming request using access_lua below is conf,


#---------------------------------------------------------------------------
 location
/ {
 
#----- call module at beginning of block -----#
 access_by_lua_file
./lua/nginx_ss.lua;


#---------------------------------------------------------------------------


nginx_ss.lua


First tries:

local packets = '{"some" : "data" }'
local curl_post_ss = 'curl to remote_server_command'
result
= os.execute(curl_post_ss)



I go to know os.execute is not lua friendly and is thread blocking call.


Second Tries :

###nginx_ss.lua
local packets = '{"some" : "data" }'
res
= ngx.location.capture( '/foo/bar', { method = ngx.HTTP_POST, body = packets } )

##nginx.conf
location
/foo/bar {
 proxy_pass http
://remote_server_endpoint;
 
}



But above method is also not giving performance, after benchmarking, new results are only 300 req/sec with 1 core 2gb ram. And without nginx_ss.lua its 1900req/sec

so considering my requirement, is there any fire-and-forget approach in lua boundary that can help in achieving above threshold. Can https://github.com/liseen/lua-resty-http can help
me through this. Is there any other hack to achieve the performance ?

Thanks you.

Yichun Zhang (agentzh)

unread,
Feb 10, 2016, 3:37:01 PM2/10/16
to openresty-en
Hello!

On Wed, Feb 10, 2016 at 3:15 AM, Sunny GUPTA wrote:
> I go to know os.execute is not lua friendly and is thread blocking call.
>

Yeah, it's horrible.

>
> Second Tries :
>
> ###nginx_ss.lua
> local packets = '{"some" : "data" }'
> res = ngx.location.capture( '/foo/bar', { method = ngx.HTTP_POST, body =
> packets } )
>
> ##nginx.conf
> location /foo/bar {
> proxy_pass http://remote_server_endpoint;
> }
>

Using the lua-resty-http-simple library can often be more efficient
than ngx.location.capture + ngx_proxy:

https://github.com/bakins/lua-resty-http-simple

Also, ensure you have enabled backend connection pooling in both your
proxy_pass and lua-resty-http-simple.

> But above method is also not giving performance, after benchmarking, new
> results are only 300 req/sec with 1 core 2gb ram. And without nginx_ss.lua
> its 1900req/sec
>

When talking about performance, it's always recommended to generate
flame graphs to get insights about any differences:

https://openresty.org/#Profiling

There's so many ways to get things wrong in a (blind) benchmark.

> so considering my requirement, is there any fire-and-forget approach in lua
> boundary that can help in achieving above threshold. Can
> https://github.com/liseen/lua-resty-http can help
> me through this. Is there any other hack to achieve the performance ?
>

I think you need to use the ngx.timer.at() API to do async processing.
Please ensure that you have read the documentation about
ngx.timer.at() carefully since there's some caveats about async
processing models (in general).

Best regards,
-agentzh

Sunny GUPTA

unread,
Feb 14, 2016, 1:51:47 PM2/14/16
to openresty-en
Thanks alot Agentzh. ngx.time.at() worked. Below is the snippet thats calling remote server in async mode without much affecting the pure nginx request processing.

local function push_data(premature)

        local hc = http:new()
        local ok, code, headers, status, body  = hc:request {
        url = server_end_url,
        method = "POST",
        timeout = _sstimeout,
        body = final_json
        }
end

--Calling endpoint
ngx.timer.at(0, push_data)
Reply all
Reply to author
Forward
0 new messages