Haproxy graceful reload

I was looking for a solution for graceful reload of haproxy. I have a nginx server running which passes requests to Haproxy and at times I reload the Haproxy configuration. But I am observing that at time of reloading all the existing connections are getting cut off and haproxy backend queue shows 0 requests ( got from socket stats of haproxy ) .

I am using the method mentioned in several blog posts and haproxy documentation about the issue :

Reload :

haproxy -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid -D -sf (</var/run/haproxy.pid)

Start :

haproxy -D  -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid 

It be grateful if someone could suggest any solution. Below is my haproxy config file

global
  maxconn 64000
  ulimit-n 200000
  log             127.0.0.1       local0
  log             127.0.0.1       local1 notice
  spread-checks 5
  stats socket /etc/haproxy/stats

defaults
  log global
  mode http
  balance roundrobin
  maxconn 64000
  option abortonclose
  option httpclose
  retries 3
  option redispatch
  timeout client 30000
  timeout connect 30000
  timeout server 30000
  stats enable
  stats uri     /haproxy?stats
  stats realm   Haproxy Statistics
  stats auth    haproxy:stats
  timeout check 5000

Solution 1:

The command you posted does not seem 100% correct to me. On my system, it reads:

haproxy -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid -D -sf $(cat /var/run/haproxy.pid)

You mistyped the value of last option -sf.

Solution 2:

This may be expected depending on your testing methodology. Although as mentioned above, you also seemed to be missing a $ near the end of your reload command?

When HAProxy does the 'reload' it starts a new HAProxy process, sends session data down a unix domain socket from the first process to the second process, the first process unbinds from the TCP ports it's listening on, and the second process binds. The first process then terminates. So they do not share memory at any stage and don't seem to sync file descriptors (from my own testing anyway). So the main point of the reload is that persistence tables (such as the cookie-based hash) are maintained so that the client will reconnect to the required backend server. However it should be graceful in the sense that connections are drained from the first process rather than instantly dropped.

If you watch your process table while performing the reload then you should observe the above, unless things have changed since I tested (a few months ago).