Hi,

I'm experiencing also some issues with the reuse of idle connections with the health checks.

Le 02/09/2025 à 6:18 PM, Daniel Lenar a écrit :
Hello,

I was struggling to get connection reuse working when check_reuse_pool was enabled. My patch addresses what I had to do to get see TCP connections being reused with my haproxy configuration below.

I had very simplistic haproxy.cfg. The IPs and hostnames have been redacted.

global
     log stdout format raw local0
     daemon

     stats socket /tmp/stats

frontend main
     bind *:8080
     mode http
     option httplog
     option http-keep-alive
     log global

     use_backend https:example.com

backend https:example.com
     mode http
     option httpchk GET /ready HTTP/1.1
    http-check send hdr Connection keep-alive hdr Host example.com hdr User- Agent "Health-Check"
     http-reuse always
    default-server maxconn 2000 check-reuse-pool inter 3000 pool-purge-delay 60s check ssl verify none
     server servara  10.0.0.1:443
     server serverb 10.0.0.2:443
     server serverc 10.0.0.3:443


The tcpcheck_use_nondefault_connect() function was considering SSL as a none default connection. If your backed servers were using SSL, then you couldn’t reuse connections. In terms of http/https, only http backends were eligible for connection reuse.

I quickly reviewed your patch. I guess it could be good to check both the server and health-check are configured to use the same transport protocol.


When looking at the code, I was health check connections were being marked private, so it didn’t allow for connection to be reused. In my patch, I check if  check-reuse-pool is enabled and make sure the connection is not private. I also set the hash key.

Indeed, these connections should not been marked as private to be reused. But when this is done, it means the connection was not coming from a connection pool. The idea is not to create a dedicated pool for health-checks but to reuse connections used for regular traffic. So, as far as possible, we should make it possible instead of splitting the pools. Especially because only one connection per server will be used for health-checks. So using a pool for it is not really useful.

There is potentially another bug that this patch doesn’t address. If the intention was for health checks to reuse the same connections from regular traffic, then that is not currently occurring. Regular traffic and health checks generate different hash keys. My patch at least makes that health checks will reuse an existing TCP connection that was initially created for health checking.

It is exactly the issue I experienced. I must check with Amaury how to fix it. The first intent for check-reuse-pool option was to make it works with the reverse connect.

The last part of the patch is to ensure that all the data is read for http health checks when check-reuse-pool  is set. This ensures that connection reuse can be safely reused for the next health checks. The health check I was working with was sending a very large json, so the read() system didn’t always read the entire message at the time. So, the connection would get closed as there were still more bytes to be read from the socket.


I must carefully review this part. At first glance, we should at least add a flag to be sure the connection was indeed reused. But it is probably trickier. The HTTP checks were not designed to drain data.

I will try to find some time to work on it. But first, I must finish my work on the issue #3081 (SNI HTTP Host header submitted on backend server by default).

Regards,
--
Christopher Faulet


Reply via email to