It seems like HAProxy doesn't allow this. We have Tomcat servers on the backend and are planning to use Apache + mod_jk to load balance. We're considering switching to something more full-featured like Netscaler but I'm not sold since part of what I'm looking for is the ability to do a seamless deployment where I could remove one of the Tomcat servers from the load balancer before rebooting it.
HAProxy allows you to do this by passing a command into the stats socket to disable the server. This will drain the connections (existing connections to this server will persist, but no new connections will be made to it).
This page gives a good summary of the commands available: http://code.google.com/p/haproxy-docs/wiki/UnixSocketCommands
and a disable example:
echo "disable server <backend_name>/<server_name>" | socat stdio /var/run/haproxy.stat
where /var/run/haproxy.stat is the UNIX domain socket for the commands, which is configured in the haproxy config file like so:
global stats socket /var/run/haproxy.stat mode 600 level admin
alongside any other global options.
Not you don't have to communicate on the socket via socat, you can connect to it like any other UNIX domain socket, which is quite straightforward in Python, Perl, PHP, C, etc. socat is mainly used in examples for convenience.
Apache can do it if you use
mod_proxy instead of
mod_proxy_balancer can integrate with
mod_status for a mess-with-balancer-nodes page. See here.
So long as your application allows user session-state to be served from all of the servers behind the load-balancer, pretty much all load-balancers support this. If your application sessions are sticky to the physical server the user is communicating with, your best bet is to disallow new connections to the server you want to take out of service and wait until the sessions have all closed. Depending on your app, this could be seconds or hours.
NGINX will allow you to do this, and to do non-fair load balances.
upstream Defintion blocks allow you to set various settings about the upstream servers that requests will be sent to.
- This server is down
- This server is only for backup, do not use if any other servers are up
- stop using this server if it fails more than X times
- how often to retest an upstream to see if it is back up
- weighting each server, allowing you to direct traffic to where your capacity is.
- use 'ip_hash', which will make clients 'sticky' to a backend as long as it is up. The same client will always go to the same backend, this is required by some applications that have persistent session data that is not replicated to the other upstreams
There is also the proxy_next_upstream setting which allows you to have NGINX automatically try a different backend if one returns an unsatisfactory result.
An alternative to @James Little's suggestion of socat you could also use hatop to connect to the HAProxy CLI to run the disable (or any of the other commands):
hatop -s /var/run/haproxy.stat
Then hit 5 (listed as 5-CLI in the bottom left menu bar). This will provide you with a prompt where you can enter commands for HAProxy.