openresty / lua-resty-limit-traffic

Lua library for limiting and controlling traffic in OpenResty/ngx_lua
821 stars 153 forks source link

attempt to call method 'expire' (a nil value) #33

Open gzliudan opened 6 years ago

gzliudan commented 6 years ago

2018/04/08 00:17:58 [error] 1176#1176: *9 lua entry thread aborted: runtime error: /usr/local/openresty/lualib/resty/limit/count.lua:53: attempt to call method 'expire' (a nil value) stack traceback: coroutine 0: /usr/local/openresty/lualib/resty/limit/count.lua: in function 'incoming' /usr/local/openresty/lualib/resty/limit/traffic.lua:26: in function 'combine'

agentzh commented 6 years ago

@gzliudan Seems like you call the API in a wrong way. You passed nil values to combine() instead of proper objects.

SvenAlHamad commented 6 years ago

I've got the same problem.

This is my error log line:

2018/08/21 12:06:05 [error] 2282#2282: *1 lua entry thread aborted: runtime error: /usr/local/openresty/lualib/resty/limit/count.lua:53: attempt to call method 'expire' (a nil value)
stack traceback:
coroutine 0:
    /usr/local/openresty/lualib/resty/limit/count.lua: in function 'incoming'
    /etc/openresty/scripts/proxy.lua:272: in function 'apply_static_rate_limiting'
    /etc/openresty/scripts/proxy.lua:304: in function 'go'
    access_by_lua(nginx.conf:144):2: in function <access_by_lua(nginx.conf:144):1>, client: 127.0.0.1, server: _, request: "GET /assets/file.txt HTTP/1.1", host: "www.example.com"

What I've noticed was that once I restart openresty, the first 3 or 4 requests fail with this error, and then it just starts working fine. This is the situation everytime I restart openresty.

Here is how my function looks like, the one that implements the method that is failing:

local function apply_static_rate_limiting()
    -- rate: 5000 requests per 3600s
    local lim, err = limit_count.new("static_limit_count_store", 5000, 3600)

    if not lim then
        ngx.log(ngx.ERR, "failed to instantiate a resty.limit.count object: ", err)
        return ngx.exit(500)
    end

    local key = ngx.var.w_real_client_ip
    local delay, err = lim:incoming(key, true)

    if not delay then
        if err == "rejected" then
            ngx.header["X-RateLimit-Limit"] = "5000"
            ngx.header["X-RateLimit-Remaining"] = 0
            return ngx.exit(503)
        end

        ngx.log(ngx.ERR, "failed to limit count: ", err)
        return ngx.exit(500)
    end

    -- the 2nd return value holds the current remaining number
    -- of requests for the specified key.
    local remaining = err

    ngx.header["X-RateLimit-Limit"] = "5000"
    ngx.header["X-RateLimit-Remaining"] = remaining
end
hungdq11 commented 6 years ago

Maybe you missed the lua block

init_by_lua_block {
    require "resty.core"
}
SvenAlHamad commented 6 years ago

Thanks @hungdq11, this sorted the issue! 🥇

joelsdc commented 3 years ago

I've run into the same/similar issue:

2021/09/30 16:30:11 [error] 9579#9579: *452377 lua entry thread aborted: runtime error: /usr/local/share/lua/5.1/resty/limit/count.lua:53: attempt to call method 'expire' (a nil value)
stack traceback:
coroutine 0:
    /usr/local/share/lua/5.1/resty/limit/count.lua: in function 'incoming'
    /etc/nginx/snippets/rate-limit.ljbc: in function </etc/nginx/snippets/rate-limit.ljbc:0>, client: 181.98.154.134, server: my.domain.name, request: "POST /my/endpoint/path HTTP/1.1", host: "my.domain.name"

I'm going to try the solution proposed by @hungdq11 and report back! Thanks.

joelsdc commented 3 years ago

I can confirm the fix worked. Thanks @hungdq11 for the tip.