apache / apisix

The Cloud-Native API Gateway
https://apisix.apache.org/blog/
Apache License 2.0
14.46k stars 2.52k forks source link

request help: How to current limit both in minutes and day by using plugin limit-count #6197

Open 123libohan opened 2 years ago

123libohan commented 2 years ago

Issue description

How to current limit both in minutes and day by using plugin limit-count? current,the plugin limit-count only Set a traffic limiting mode, Second or minute,If I want to set seconds and minutes at the same time,plugin not support,Because what you set later overwrites what you set earlier,Is there a better solution to this problem?thank you

Environment

XW512 commented 2 years ago

+1,I also want to know if there is a solution

xuminwlt commented 2 years ago

See https://zhangge.net/5158.html May help u.

123libohan commented 2 years ago

See https://zhangge.net/5158.html May help u.

Thank you but this plugin also can not limit both in minutes and day on one cunsumer at the same time.

See https://zhangge.net/5158.html May help u.

Thank you but this plugin also can not limit both in minutes and day on one cunsumer at the same time.

tokers commented 2 years ago

Currently, the only way that you can run a plugin twice is through the global rule and per-requests' route level plugins.

spacewander commented 2 years ago

In the future, we can implement it via https://github.com/openresty/lua-resty-limit-traffic/blob/master/lib/resty/limit/traffic.md#combine?

123libohan commented 2 years ago

In the future, we can implement it via https://github.com/openresty/lua-resty-limit-traffic/blob/master/lib/resty/limit/traffic.md#combine?

Ok thank you very much. When will it be available in the official version?

HelloBug0 commented 2 years ago

Sorry, I am not quite clear [minutes and day] in limit-count plugin. Do you mean the time_window parameter in minutes or in day?

HelloBug0 commented 2 years ago

@123libohan

123libohan commented 2 years ago

Sorry, I am not quite clear [minutes and day] in limit-count plugin. Do you mean the time_window parameter in minutes or in day?

Yes ,I mean the time_window, for an example , I want to limit access on one cunsumer 30 times per minute and 1000 times per day together

HelloBug0 commented 2 years ago

Sorry, I am not quite clear [minutes and day] in limit-count plugin. Do you mean the time_window parameter in minutes or in day?

Yes ,I mean the time_window, for an example , I want to limit access on one cunsumer 30 times per minute and 1000 times per day together

I see. Thanks for your reply.

HelloBug0 commented 2 years ago

Is it a good idea if we organize some parameters of schema properties, like count, time_window, key, rejected_code, etd to a array? Than we cann deal with all these limiters as a array using lua-resty-limit-traffic. And it seems that other plugins like limit-req could do the same change. @spacewander

spacewander commented 2 years ago

We should also deal with redis backend too?

HelloBug0 commented 2 years ago

We should also deal with redis backend too?

I think we could do that just as we do now.

wilson-1024 commented 2 years ago

I want to write a new plugin to implement this function. can it be assigned to me?

spacewander commented 2 years ago

Can it be done in this plugin?

wilson-1024 commented 2 years ago

I can try it

123libohan commented 2 years ago

Can it be done in this plugin?

Thanks,I think it can be done in this plugin. In addition, is it possible to place the configuration in the same Redis key? In this way, the query of the limit-count only needs to be performed once, and the time consuming will not be affected by the multiple query of Redis.

XFarooqi commented 1 year ago

Hi @123libohan I would like to work on the issue.

Can you please guide me on what should be the expected input to the time_window parameter of the limit-count plugin? Or should we add a new parameter?

Please, describe the issue with some examples"

membphis commented 1 year ago

@spacewander can you help @XFarooqi ?

What can he do now?

spacewander commented 1 year ago

IMHO, maybe we can create several limit counters with different time_window, and combine their results?

wilson-1024 commented 1 year ago

@spacewander Sorry, I've been busy with work lately and may not have time to finish this

monkeyDluffy6017 commented 1 year ago

IMHO, maybe we can create several limit counters with different time_window, and combine their results?

Sounds easy to achieve, but is it more efficient to use one count and support at the library lua-resty-limit-traffic?

ro4i7 commented 1 year ago

Hello @spacewander @membphis @123libohan please assign it to me and give the feedback on the following solution;

To limit both in minutes and days using the limit-count plugin, we can create two separate rules for the different time periods. One rule can limit the requests per minute, while the other rule can limit the requests per day.

a configuration for limiting requests to 1000 per minute and 50000 per day:

plugins:
  limit-count:
    minute: 1000
    hour: 0
    day: 0
    month: 0
    year: 0
    key: "${remote_addr}"
    rejected_code: 503
    redis_host: "127.0.0.1"
    redis_port: 6379
    dict_name: "limit_count"

  limit-count-daily:
    minute: 0
    hour: 0
    day: 1
    month: 0
    year: 0
    key: "${remote_addr}"
    rejected_code: 503
    redis_host: "127.0.0.1"
    redis_port: 6379
    dict_name: "limit_count_daily"

The first rule limit-count limits the requests to 1000 per minute, and the second rule limit-count-daily limits the requests to 50000 per day. We can adjust the limits and the time periods as needed.

I have used Redis as the storage backend for the limit-count plugin. We may need to adjust the redis_host and redis_port settings to match our Redis configuration.

spacewander commented 1 year ago

Solving it by using a new plugin is unacceptable. We should solve it by using the same plugin and in one configuration.

ro4i7 commented 1 year ago

Solving it by using a new plugin is unacceptable. We should solve it by using the same plugin and in one configuration.

@spacewander I have seen in the above comment that to use resty.limit.traffic for this in the future. my solution is based on this:

local limit_req = require("resty.limit.traffic")

-- set traffic limits in both minutes and days
local minute_limit = 100
local day_limit = 1000

-- create a traffic limiter
local limiter, err = limit_req.new("my_traffic_limiter", minute_limit, day_limit, 3600)
if not limiter then
    ngx.log(ngx.ERR, "failed to create limiter: ", err)
    return ngx.exit(500)
end

-- call the limiter
local delay, err = limiter:incoming(ngx.var.binary_remote_addr, true)
if not delay then
    if err == "rejected" then
        ngx.log(ngx.NOTICE, "traffic rejected")
        return ngx.exit(429)
    end
    ngx.log(ngx.ERR, "failed to limit traffic: ", err)
    return ngx.exit(500)
end

-- set the delay (in seconds) if necessary
if delay >= 0.001 then
    ngx.sleep(delay)
end

created a traffic limiter with a minute limit of 100 and a day limit of 1000.

spacewander commented 1 year ago

Solving it by using a new plugin is unacceptable. We should solve it by using the same plugin and in one configuration.

@spacewander I have seen in the above comment that to use resty.limit.traffic for this in the future. my solution is based on this:

local limit_req = require("resty.limit.traffic")

-- set traffic limits in both minutes and days
local minute_limit = 100
local day_limit = 1000

-- create a traffic limiter
local limiter, err = limit_req.new("my_traffic_limiter", minute_limit, day_limit, 3600)
if not limiter then
    ngx.log(ngx.ERR, "failed to create limiter: ", err)
    return ngx.exit(500)
end

-- call the limiter
local delay, err = limiter:incoming(ngx.var.binary_remote_addr, true)
if not delay then
    if err == "rejected" then
        ngx.log(ngx.NOTICE, "traffic rejected")
        return ngx.exit(429)
    end
    ngx.log(ngx.ERR, "failed to limit traffic: ", err)
    return ngx.exit(500)
end

-- set the delay (in seconds) if necessary
if delay >= 0.001 then
    ngx.sleep(delay)
end

created a traffic limiter with a minute limit of 100 and a day limit of 1000.

Limit traffic doesn't have a method called new. See https://github.com/openresty/lua-resty-limit-traffic/blob/master/lib/resty/limit/traffic.md

buzzlightyear2k commented 1 year ago

Did anyone have solution for this problem ?