Hello,
I have 2+ servers running on one VM, and I want to only process one HTTP request at a time across all of them (they’re performing brief, mem and CPU-intensive work).
Protect Servers with HAProxy Connection Limits and Queues - HAProxy Technologies says if mode http
is set, “the maxconn
parameter on a server
line … relates to the number of concurrent HTTP requests.”
That’s close to what I need, but maxconn
in frontend
or global
seems to mean connections, not requests.
Is there some way to achieve this? Thanks-
Two configs I’ve tried:
global
maxconn 1
frontend MyFrontend1
bind 127.0.0.1:3001
default_backend rpc_1
backend rpc_1
mode http
server s1 127.0.0.1:31234
frontend MyFrontend2
bind 127.0.0.1:3002
default_backend rpc_2
backend rpc_2
mode http
server s2 127.0.0.1:31235
frontend rpc
mode http
bind :3001
bind :3002
maxconn 1
use_backend rpc_1 if { dst_port 3001 }
use_backend rpc_2 if { dst_port 3002 }
Came up with this approach. The extra hop adds a noticeable amount of latency though.
# Funnel all requests through a single pipe ...
frontend Intake
mode http
bind :3001
bind :3002
http-request add-header x-forwarded-port %[dst_port]
use_backend Layer1b
backend Layer1b
mode http
server sl1b 127.0.0.1:4000 maxconn 1
# ... and then re-route to different backends
frontend Route
mode http
bind :4000
acl is3001 hdr(x-forwarded-port) -i 3001
acl is3002 hdr(x-forwarded-port) -i 3002
use_backend rpc_1 if is3001
use_backend rpc_2 if is3002
backend rpc_1
mode http
server s1 127.0.0.1:31234 maxconn 2
backend rpc_2
mode http
server s2 127.0.0.1:31235 maxconn 2
I find that hard to believe. You said that a request causes mem and CPU intensive work, so this should be completely negligible.
Maybe you benchmarked with empty request, and therefore benchmarked basically connection setup time?
That said, I can think of another way in this particular case. You can adjust the destination port dynamically in the backend with set-dst-port [1] :
frontend fe_in
bind :3001
bind :3002
use_backend be_out
backend be_out
http-request set-dst-port int(31234) if { dst_port 3001 }
http-request set-dst-port int(31235) if { dst_port 3002 }
server s1 127.0.0.1:80 maxconn 1
The port specified in the server configuration really doesn’t matter then.
[1] HAProxy version 2.6.15-62 - Configuration Manual
Yes, I was benchmarking an empty response. It added 1-2 ms vs. a single transparent frontend+backend proxy, with 50 concurrent connections.
Thanks for the idea. That worked with minor changes (mode http
and 0.0.0.0:0
in the server line) and got rid of the additional latency.
frontend fe_in
mode http
bind :3001
bind :3002
use_backend be_out
backend be_out
mode http
http-request set-dst-port int(31234) if { dst_port 3001 }
http-request set-dst-port int(31235) if { dst_port 3002 }
server s1 0.0.0.0:0 maxconn 1