Re: Rate Limiting with token/leaky bucket algorithm

2022-06-07 Thread Seena Fallah
Got it!
Thanks. Works like a charm =)

On Tue, 7 Jun 2022 at 17:50, Willy Tarreau  wrote:

> On Tue, Jun 07, 2022 at 01:51:06PM +0200, Seena Fallah wrote:
> > I also tried with this one but this will give me 20req/s 200 OK and the
> > rest of it 429 too many requests
> > ```
> > listen test
> > bind :8000
> > stick-table  type ip  size 100k expire 30s store http_req_rate(1s)
> > acl exceeds_limit src_http_req_rate gt 100
> > http-request track-sc0 src unless exceeds_limit
> > http-request deny deny_status 429 if exceeds_limit
> > http-request return status 200 content-type "text/plain" lf-string
> "200
> > OK"
> > ```
> >
> > Maybe the "1s" isn't handled correctly? when I fetch the current value
> for
> > the http_req_rate it is 100 so that makes sense other requests get 429
> but
> > actually, only 20req/s is responding "200" because the http_req_rate is
> not
> > decreasing in the correct intervals!
>
> There is a reason to this, which is subtle: the counter is updated when
> the track action is performed. As such, each new request refreshes the
> counter and the counter reports the total number of *received* requests
> and not the number of accepted requests.
>
> There are different ways to deal with this, usually they involve a check
> *before* the track. With your config it's trivial since you're already
> using src_http_req_rate which performs its own lookup. Just move the
> track_sc rule at the end and it should be OK.
>
> Willy
>


Re: Rate Limiting with token/leaky bucket algorithm

2022-06-07 Thread Willy Tarreau
On Tue, Jun 07, 2022 at 01:51:06PM +0200, Seena Fallah wrote:
> I also tried with this one but this will give me 20req/s 200 OK and the
> rest of it 429 too many requests
> ```
> listen test
> bind :8000
> stick-table  type ip  size 100k expire 30s store http_req_rate(1s)
> acl exceeds_limit src_http_req_rate gt 100
> http-request track-sc0 src unless exceeds_limit
> http-request deny deny_status 429 if exceeds_limit
> http-request return status 200 content-type "text/plain" lf-string "200
> OK"
> ```
> 
> Maybe the "1s" isn't handled correctly? when I fetch the current value for
> the http_req_rate it is 100 so that makes sense other requests get 429 but
> actually, only 20req/s is responding "200" because the http_req_rate is not
> decreasing in the correct intervals!

There is a reason to this, which is subtle: the counter is updated when
the track action is performed. As such, each new request refreshes the
counter and the counter reports the total number of *received* requests
and not the number of accepted requests.

There are different ways to deal with this, usually they involve a check
*before* the track. With your config it's trivial since you're already
using src_http_req_rate which performs its own lookup. Just move the
track_sc rule at the end and it should be OK.

Willy



Re: Rate Limiting with token/leaky bucket algorithm

2022-06-07 Thread Seena Fallah
I also tried with this one but this will give me 20req/s 200 OK and the
rest of it 429 too many requests
```
listen test
bind :8000
stick-table  type ip  size 100k expire 30s store http_req_rate(1s)
acl exceeds_limit src_http_req_rate gt 100
http-request track-sc0 src unless exceeds_limit
http-request deny deny_status 429 if exceeds_limit
http-request return status 200 content-type "text/plain" lf-string "200
OK"
```

Maybe the "1s" isn't handled correctly? when I fetch the current value for
the http_req_rate it is 100 so that makes sense other requests get 429 but
actually, only 20req/s is responding "200" because the http_req_rate is not
decreasing in the correct intervals!

On Fri, 3 Jun 2022 at 17:44, Seena Fallah  wrote:

> Do you see any diff between my conf and the one in the link? :/
>
> On Fri, 3 Jun 2022 at 17:37, Aleksandar Lazic  wrote:
>
>> Hi.
>>
>> On Fri, 3 Jun 2022 17:12:25 +0200
>> Seena Fallah  wrote:
>>
>> > When using the below config to have 100req/s rate-limiting after passing
>> > the 100req/s all of the reqs will deny not reqs more than 100req/s!
>> > ```
>> > listen test
>> > bind :8000
>> > stick-table  type ip  size 100k expire 30s store http_req_rate(1s)
>> > http-request track-sc0 src
>> > http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 }
>> > http-request return status 200 content-type "text/plain" lf-string
>> "200
>> > OK"
>> > ```
>> >
>> > Is there a way to deny reqs more than 100 not all of them?
>> > For example, if we have 1000req/s, 100reqs get "200 OK" and the rest of
>> > them (900reqs) gets "429"?
>>
>> Yes.
>>
>> Here are some examples with explanation.
>> https://www.haproxy.com/blog/four-examples-of-haproxy-rate-limiting/
>>
>> Here some search outputs, maybe some of the examples helps you to.
>> https://html.duckduckgo.com/html?q=haproxy%20rate%20limiting
>>
>> Regards
>> Alex
>>
>


Re: Rate Limiting with token/leaky bucket algorithm

2022-06-03 Thread Seena Fallah
Do you see any diff between my conf and the one in the link? :/

On Fri, 3 Jun 2022 at 17:37, Aleksandar Lazic  wrote:

> Hi.
>
> On Fri, 3 Jun 2022 17:12:25 +0200
> Seena Fallah  wrote:
>
> > When using the below config to have 100req/s rate-limiting after passing
> > the 100req/s all of the reqs will deny not reqs more than 100req/s!
> > ```
> > listen test
> > bind :8000
> > stick-table  type ip  size 100k expire 30s store http_req_rate(1s)
> > http-request track-sc0 src
> > http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 }
> > http-request return status 200 content-type "text/plain" lf-string
> "200
> > OK"
> > ```
> >
> > Is there a way to deny reqs more than 100 not all of them?
> > For example, if we have 1000req/s, 100reqs get "200 OK" and the rest of
> > them (900reqs) gets "429"?
>
> Yes.
>
> Here are some examples with explanation.
> https://www.haproxy.com/blog/four-examples-of-haproxy-rate-limiting/
>
> Here some search outputs, maybe some of the examples helps you to.
> https://html.duckduckgo.com/html?q=haproxy%20rate%20limiting
>
> Regards
> Alex
>


Re: Rate Limiting with token/leaky bucket algorithm

2022-06-03 Thread Aleksandar Lazic
Hi.

On Fri, 3 Jun 2022 17:12:25 +0200
Seena Fallah  wrote:

> When using the below config to have 100req/s rate-limiting after passing
> the 100req/s all of the reqs will deny not reqs more than 100req/s!
> ```
> listen test
> bind :8000
> stick-table  type ip  size 100k expire 30s store http_req_rate(1s)
> http-request track-sc0 src
> http-request deny deny_status 429 if { sc_http_req_rate(0) gt 100 }
> http-request return status 200 content-type "text/plain" lf-string "200
> OK"
> ```
> 
> Is there a way to deny reqs more than 100 not all of them?
> For example, if we have 1000req/s, 100reqs get "200 OK" and the rest of
> them (900reqs) gets "429"?

Yes.

Here are some examples with explanation.
https://www.haproxy.com/blog/four-examples-of-haproxy-rate-limiting/

Here some search outputs, maybe some of the examples helps you to.
https://html.duckduckgo.com/html?q=haproxy%20rate%20limiting

Regards
Alex