The first in a series of work related posts, put here for my own reference, but also in the hope it’ll help others.

Today, we’re going to look at sort of reversing the good work done by a load balancer by allowing connections to two Linux servers point to one backend service. This would only generally be used if your load balanced servers perform more than one task where load balancing is beneficial for some of these services or as a stepping stone until the backend service is replicated on another server for load balancing. A similar setup could be used to translate ports.

To make things easier to visualise, the following diagram is what we’re going to achieve:

The ideal result

The ideal result

Here, the request comes in from the cloud (a user on the Internet), and hits either server 1 or 2 depending on which server the load balancer picks. Then, the server the user connects to passes the request onto the backend server. The goal is for the user to be able to reach this backend service regardless to which front end server they land on. We’re using this as a solution on two load balanced servers sitting in Microsoft Windows Azure until we start load balancing the backend service (which at the moment is hosted in a different data centre).

For this, we’re going to be using HAProxy, a light weight TCP/HTTP load balancing proxy server with “High Availability” in mind (hence the HA part of the name). We’re going to use this in an unconventional way, as Azure already load balances the two servers (as they are both part of the same, in Azure terms, “cloud service”), we’re going to install HAProxy on both servers and have them both point at one backend server. Once this is done, we will use the following configuration to set up the proxy, which is essentially in two parts. I’ll explain both parts as we go along:
backend servicename
mode tcp
timeout connect 60s
timeout server 5m
balance roundrobin
server server1 <>:<> maxconn 4096

Here we have defined the backend server and given it a name (in this example – servicename – but this should be changed to something more suitable), set it to TCP mode as the service we’re routing to isn’t a web server. Timeouts are set to 60 seconds to connect to the backend server, and a 5 minute time out for active connections. The balance flag is required, even with only one server defined. At this point, I should point out, if you want to use this solution to simply translate ports, you’d put your local service here, then in the following section, set the bind to the port you want to translate to.
frontend service_proxy
bind <>:<>
timeout client 5m
default_backend servicename

The other half of the config is defining the side the user interfaces with. Here we’ve named the front end service_proxy, the next line defines where HAProxy should be listening for incoming connections, if you set this to * (an asterisk) then this will accept requests from any address. The timeout here is set for 5 minutes, if the client doesn’t respond in that time, HAProxy will close the connection. Finally, we tell HAProxy to point all requests to the backend we defined earlier.

Once HAProxy is running on the two servers, both should be accepting traffic and forward it to the same backend server.