On Sun, Jun 7, 2020 at 11:11 PM Илья Шипицин <[email protected]> wrote:

>
>
> вс, 7 июн. 2020 г. в 19:59, Stefano Tranquillini <[email protected]>:
>
>> Hello all,
>>
>> I'm moving to HA using it to replace NGINX and I've a question regarding
>> how to do a Rate Limiting in HA that enables queuing the requests instead
>> of closing them.
>>
>> I was able to limit per IP following those examples:
>> https://www.haproxy.com/blog/four-examples-of-haproxy-rate-limiting/ .
>> However, when the limit is reached, the users see the error and connection
>> is closed.
>>
>> Since I come from NGINX, it has this handy feature
>> https://www.nginx.com/blog/rate-limiting-nginx/ where connections that
>> exceed the threshold are queued. Thus the user will still be able to do the
>> calls but be delayed without him getting errors and keep the overall number
>> of requests within threshold.
>>
>> Is there anything similar in HA? It should limit/queueing the user by IP.
>>
>> To explain with an example, we have two users Alice, with ip A.A.A.A and
>> Bob with ip B.B.B.B The threshold is 30r/minute.
>>
>> So in 1 minute:
>>
>>    - Alice does 20 requests. -> that's fine
>>    - Bob does 60 requests. -> the system caps the requset to 30 and then
>>    process the other 30 later on (maybe also adding timeout/delay)
>>    - Alice does 50 request -> the first 40 are fine, the next 10 are
>>    queued.
>>    - Bob does 20 requests -> they are queue after the one above.
>>
>> I saw that it can be done in general, by limiting the connections per
>> host. But this will mean that it's cross IP and thus, if 500 is the limit
>> - Alice  does 1 call
>> - Bob does 1000 calls
>> - Alice does another 1 call
>> - Alice will be queued, that's not what i would like to have.
>>
>> is this possible? Is there anything similar that can be done?
>>
>
> it is not cross IP.  I wish nginx docs would be better on that.
>
What do you mean?
in nginx i do
limit_req_zone $binary_remote_addr zone=prod:10m rate=40r/m;
and works

first, in nginx terms it is limited by zone key. you can define key using
> for example $binary_remote_addr$http_user_agent$ssl_client_ciphers
> that means each unique combination of those parameters will be limited by
> its own counter (or you can use nginx maps to construct such a zone key)
>
> in haproxy you can see and example of
>
> # Track client by base32+src (Host header + URL path + src IP)
> http-request track-sc0 base32+src
>
> which also means key definition may be as flexible as you can imagine.
>

the point is, how can i cap the number of requests for a single user to
40r/minute for example? or any number.

What I was able to do is to slow it down in this way, but it does not
ensure the cap per request, it only adds 500ms to each call.

frontend proxy
    bind *:80
    # ACL function declarations
    acl is_first_level src_http_req_rate(Abuse) ge 30
    use_backend api_delay if is_first_level
    use_backend api

backend api
    server api01 api01:80
    server api02 api02:80
    server api03 api03:80

backend api_delay
    tcp-request inspect-delay 500ms
    tcp-request content accept if WAIT_END
    server api01 api01:80
    server api02 api02:80
    server api03 api03:80

backend Abuse
    stick-table type ip size 100k expire 15s store http_req_rate(10s)


>
>
>>
>> Thanks
>>
>>
>> --
>> *Stefano*
>>
>>

-- 
Stefano

Reply via email to