A little from column A, a little from column B :)
For the sake of uptime, you should definitely be using health checks in HAProxy regardless of anything else. If one of your backend nodes goes down, you want HAProxy to stop sending requests to it. The failure doesn't have to be in your application, could be hardware, network, whatever. This is pretty straightforward to configure:
option httpchk GET /test HTTP/1.0\r\n
250ms sounds like a very frequent check. At that rate, your backend servers could spend a lot of time just processing health checks. You need to trade off the cost of the health checks in terms of application overhead vs how quickly you want dead nodes to be taken offline.
The second strategy is one I've used before. Figure out the total number of concurrent connections your application can handle. Then, in HAProxy, split the requests into slow and fast and allocate a proportion of your total connections to each. E.g.,
frontend myfrontend
bind *:80
acl url-slow path /some-long-running-request
use_backend slow-backend if url-slow
default_backend regular-backend
backend slow-backend
...
server backend1 1.2.3.4:80 maxconn 10
backend regular-backend
...
server backend1 1.2.3.4.:80 maxconn 90
So, say, backend1 can handle 100 concurrent connections. In the above, we allocate 90 connections to 'regular' requests and 10 connections to slow running requests. Even if you use up all of your slow connections, then the 'regular' requests will still be processed.
Good luck!
Best Answer
The easiest solution would be just use DNS to map
foo.cust.mydomain.example
to a specific server IP, as womble suggested. This would skip the entire proxy server. Perhaps this is not possible for you, for example if you do not have public IP addresses for the backend servers.Directing all requests to one server (with a wildcard DNS) and then forwarding the requests dynamically according to the Host header is a bit more complicated, and it seems HAProxy cannot do this, because every backend server must be explicitly defined in HAProxy configuration.
Nginx, though, is different, with right configuration Nginx can use Host header to choose the backend. Nginx needs a DNS server that maps names to backend addresses, of course.
Here is a small example of the configuration:
This redirects
http://myserver.cust.mydomain.example/foo/
tohttp://myserver.cust.mydomain.example/foo/
. Does not seem very helpful at first sight. But if you set up a private DNS server that maps those names to a backend server addresses, the request actually gets forwarded to a correct backend server on a private address.But, this kind of DNS server setting might not be desired, and could cause problems in some cases. So, with some additions to the Nginx config, we can take another approach:
Now redirect goes from
http://myserver.cust.mydomain.example/foo/
tohttp://myserver.private.mydomain.example/foo/
. The DNS server can hold private addresses under different domain, andproxy_pass
directive can be modified to match the desired name server configuration.I still think this kind of proxying might not be the easiest way to solve the whole picture, but it's one possibility after all. I'm happy if this was of any help.
References: Nginx Wiki, especially HttpProxyModule and HttpRewriteModule