Re: Rate Limiting with token/leaky bucket algorithm
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
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
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
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
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