Hi,
I'm experiencing a problem with backend TCP connections being reset
[RST+ACK] by HAProxy after serving one HTTP request and receiving the
[ACK] for the HTTP response. Delay between backend's [ACK] and
haproxy's [RST+ACK] seems random, ranging from single seconds to
several minutes.
What I wanted to achieve is: for each backend server keep a limited
pool of backend TCP connections open, and when a HTTP request comes in
through the frontend, reuse one of the existing connections (in HTTP
keep-alive mode), creating one if necessary.
What you are describing is connection pooling/multiplexing, but thats not
supported (yet).
It was my understanding that 'timeout server 5m' should keep backend
connections opened for 5 minutes before closing them. Was I mistaken?
Yes, this is a timeout for the case when the server is supposed to send
something, but doesn't [1], *not for a keep-alive use-case*.
Would timeout tunnel allow me to specify such timeout, despite
HAProxy working in http-keep-alive mode?
No.
Here is what you need to know (valid for the 1.5 stable releases):
- the frontend and backend connections are 1:1, meaning one frontend
connection always has one backend connection. If either of those two
connections are closed, the other side needs to close as well. You
cannot reuse a backend connection for a request coming from a
different/new frontend connection. You cannot have a backend connection
pool and reuse them for frontend requests. Its possible that this will
come in 1.6.
- with option http-tunnel [2], which was the default in 1.4 release,
the HTTP connection is transformed into a TCP tunnel, so after the
first request, HAproxy just forwards TCP between the client and the
server. This brings some problems with it. For example, ACL, content
switching and all HTTP based feature cannot work for subsequent
HTTP request in a TCP session. Keepalive does work if server and
client support it. Keepalive timeout is specified by timeout tunnel.
- with option http-keep-alive [3], which is the new 1.5 default, HAProxy
understands the keep-alive part, and looks and understand every request.
The 1:1 mapping is still valid and you still can't do connection pooling.
Keep-alive timeout is specified by timeout http-keep-alive. option
prefer-last-server [4] is recommended if you don't have any other client
stickiness configurations.
- option http-server-close [5] does keep-alive on the client side only.
timeout http-keep-alive is used here as well.
Hope this helps,
Lukas
[1]
http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#4.2-timeout%20server
[2]
http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#option%20http-tunnel
[3]
http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#option%20http-keep-alive
[4]
http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#option%20prefer-last-server
[5]
http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#option%20http-server-close