lua-resty-limit-traffic icon indicating copy to clipboard operation
lua-resty-limit-traffic copied to clipboard

Limit breaches significantly as we increase traffic

Open kkaushal09 opened this issue 5 years ago • 0 comments

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

kkaushal09 avatar May 24 '19 07:05 kkaushal09