Heartbeat Aware Load balancing
Solution 1:
You can dynamically adjust server weights with a little HAProxy Voodoo courtesy of the set weight
comand
The relevant bits (which get sent to HAProxy's stats socket):
set weight / [%]
Change a server's weight to the value passed in argument. If the value ends with the '%' sign, then the new weight will be relative to the initially configured weight. Relative weights are only permitted between 0 and 100%, and absolute weights are permitted between 0 and 256. Servers which are part of a farm running a static load-balancing algorithm have stricter limitations because the weight cannot change once set. Thus for these servers, the only accepted values are 0 and 100% (or 0 and the initial weight). Changes take effect immediately, though certain LB algorithms require a certain amount of requests to consider changes. A typical usage of this command is to disable a server during an update by setting its weight to zero, then to enable it again after the update by setting it back to 100%. This command is restricted and can only be issued on sockets configured for level "admin". Both the backend and the server may be specified either by their name or by their numeric ID, prefixed with a dash ('#').
You would of course need to write some back-end code on the servers to report their relative load, and a process on your HAProxy box would need to query them (this could be incorporated into your health checks with some creativity, but I'd start by doing it as a separate process for simplicity).
Solution 2:
The simplest way to accomplish this is to have a status page on your web servers that returns HTTP 200 if the server is fine, and HTTP 500 if it's getting overloaded. Also, if you know that a particular server can handle 20% more connections than the other you can use weights to try and stay ahead of overloading servers:
backend appservers
mode http
option httpchk HEAD /health_check.php
option redispatch
server web1 x.x.x.x:80 weight 100 check inter 2000 rise 5 fall 2
server web2 x.x.x.x:80 weight 120 check inter 2000 rise 5 fall 2
server web3 x.x.x.x:80 weight 80 check inter 2000 rise 5 fall 2