apisix icon indicating copy to clipboard operation
apisix copied to clipboard

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

Open 123libohan opened this issue 3 years ago • 27 comments

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

  • apisix version (cmd: apisix version): 2.11
  • OS (cmd: uname -a): centOS7
  • OpenResty / Nginx version (cmd: nginx -V or openresty -V): 1.19.9.1
  • etcd version, if have (cmd: run curl http://127.0.0.1:9090/v1/server_info to get the info from server-info API):
  • apisix-dashboard version, if have:
  • the plugin runner version, if the issue is about a plugin runner (cmd: depended on the kind of runner):
  • luarocks version, if the issue is about installation (cmd: luarocks --version):

123libohan avatar Jan 25 '22 07:01 123libohan

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

XW512 avatar Jan 25 '22 07:01 XW512

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

xuminwlt avatar Jan 25 '22 10:01 xuminwlt

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.

123libohan avatar Jan 25 '22 11:01 123libohan

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

tokers avatar Jan 25 '22 11:01 tokers

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

spacewander avatar Jan 26 '22 01:01 spacewander

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?

123libohan avatar Jan 26 '22 11:01 123libohan

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 avatar Feb 08 '22 12:02 HelloBug0

@123libohan

HelloBug0 avatar Feb 09 '22 12:02 HelloBug0

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

123libohan avatar Feb 10 '22 10:02 123libohan

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 avatar Feb 10 '22 11:02 HelloBug0

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

HelloBug0 avatar Feb 10 '22 13:02 HelloBug0

We should also deal with redis backend too?

spacewander avatar Feb 11 '22 03:02 spacewander

We should also deal with redis backend too?

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

HelloBug0 avatar Feb 14 '22 01:02 HelloBug0

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

wilson-1024 avatar Mar 08 '22 05:03 wilson-1024

Can it be done in this plugin?

spacewander avatar Mar 08 '22 05:03 spacewander

I can try it

wilson-1024 avatar Mar 08 '22 06:03 wilson-1024

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.

123libohan avatar Mar 08 '22 10:03 123libohan

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"

XFarooqi avatar Nov 28 '22 18:11 XFarooqi

@spacewander can you help @XFarooqi ?

What can he do now?

membphis avatar Dec 05 '22 07:12 membphis

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

spacewander avatar Dec 05 '22 07:12 spacewander

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

wilson-1024 avatar Dec 05 '22 07:12 wilson-1024

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?

monkeyDluffy6017 avatar Dec 05 '22 08:12 monkeyDluffy6017

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.

ro4i7 avatar Mar 12 '23 15:03 ro4i7

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

spacewander avatar Mar 13 '23 03:03 spacewander

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.

ro4i7 avatar Mar 20 '23 12:03 ro4i7

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

spacewander avatar Mar 21 '23 01:03 spacewander

Did anyone have solution for this problem ?

buzzlightyear2k avatar Apr 07 '23 07:04 buzzlightyear2k