lua-resty-limit-traffic
lua-resty-limit-traffic copied to clipboard
Limit breaches significantly as we increase traffic
I have noticed that the limit is not always regarded and we can see count of HTTP 200 more than set limit. This is more evident and occurs more frequently as we increase traffic. I have tried testing with actual traffic pattern seen on prod environments. Below is my implementation.
Nginx conf:
location = /xyz {
limit_conn_status 429;
limit_req_status 429;
limit_req zone=user_details burst=3920 nodelay;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Accounts-RequestId $connection:$connection_requests;
proxy_connect_timeout 10;
proxy_send_timeout 10;
proxy_read_timeout 10;
add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,Cache-Control,X-Mx-ReqToken,Keep-Alive,X-Requested-With,If-Modified-Since,X-CSRF-Token';
# Real value of this upstream will be set by access_by_lua_block block beneath
set $upstream_proxy '';
proxy_pass $upstream_proxy;
access_by_lua_file 'lua/temp.lua';
}
LUA code:
local headers = ngx.req.get_headers()
local header_authorization = headers["Authorization"]
local limit_req = require "resty.limit.req"
local lim, err = limit_req.new("my_limit_req_store", 200, 200)
if not lim then
ngx.log(ngx.ERR,"failed to instantiate a resty.limit.req object: ", err)
return ngx.exit(500)
end
if header_authorization then
local base64_enc = string.sub(header_authorization, 7)
local base64_dec = ngx.decode_base64(base64_enc)
if base64_dec ~= "clientname" then
local key = base64_dec
local delay, err = lim:incoming(key, true)
if not delay then
if err == "rejected" then
return ngx.exit(503)
end
ngx.log(ngx.ERR, "failed to limit req: ", err)
return ngx.exit(500)
end
ngx.say(key,delay,err,header_authorization)
if delay >= 0.001 then
local excess = err
ngx.sleep(delay)
end
end
end
local counter = (ngx.var.connection + ngx.var.connection_requests ) % 100
if( counter < 50 ) then
ngx.var.upstream_proxy = "https://upstream1"
else
ngx.var.upstream_proxy = "http://upstream2"
end