HTTP request throttling/rate limiting in Zato
Imagine, or recall, a scenario. You integrate three applications, two client HTTP ones and the third is a backend one (no matter the technology).
All is well except client1 tends to send requests in bursts for no good reason and its developers just cannot tame it.
The backend app can't deal with it, they prefer a steady inflow of messages, and you're tasked with containing the issue.
In that situation you can take advantage of the fact that Zato uses an embedded instance of HAProxy as its load-balancer through which HTTP apps connect so you can fire up the GUI in config's source code view and add these lines to 'frontend front_http_plain'
# At most 10 concurrent connections from a client acl too_fast fe_sess_rate ge 10 # Matches any path beginning with a given prefix acl bursts_inclined path_beg -i /client1 # Effectively working as a delay mechanism for clients that are too fast tcp-request inspect-delay 1000ms # Fast-path - accept connection if it's not this troublesome client tcp-request content accept unless bursts_inclined too_fast # The very fast client gets here meaning they have to wait full inspect-delay tcp-request content accept if WAIT_END
so the whole of if reads now:
frontend front_http_plain mode http default_backend bck_http_plain acl too_fast fe_sess_rate ge 10 acl bursts_inclined path_beg -i /client1 tcp-request inspect-delay 1000ms tcp-request content accept unless bursts_inclined too_fast tcp-request content accept if WAIT_END option httplog # ZATO frontend front_http_plain:option log-http-requests bind 127.0.0.1:11223 # ZATO frontend front_http_plain:bind maxconn 200 # ZATO frontend front_http_plain:maxconn monitor-uri /zato-lb-alive # ZATO frontend front_http_plain:monitor-uri
The GUI can be now used to validate and save the config:
There's a couple of assumptions
- Instead of HAProxy 1.4, you use 1.5 (or later, but this is the latest version as of the time of this writing)
- Each client accesses URLs beginning with a client-specific prefix - but this is a good idea anyway