16.3 Configuring Simple Load Balancing Using HAProxy

The following example uses HAProxy to implement a front-end server that balances incoming requests between two back-end web servers, and which is also able to handle service outages on the back-end servers.

Figure 16.1 shows an HAProxy server (10.0.0.10), which is connected to an externally facing network (10.0.0/24) and to an internal network (192.168.1/24). Two web servers, websvr1 (192.168.1.71) and websvr2 (192.168.1.72), are accessible on the internal network. The IP address 10.0.0.10 is in the private address range 10.0.0/24, which cannot be routed on the Internet. An upstream network address translation (NAT) gateway or a proxy server provides access to and from the Internet.

Figure 16.1 Example HAProxy Configuration for Load Balancing

The diagram shows an HAProxy server (10.0.0.10), which is connected to an externally facing network (10.0.0/24) and to an internal network (192.168.1/24). Two web servers, websvr1 (192.168.1.71) and websvr2 (192.168.1.72), are accessible on the internal network. The IP address 10.0.0.10 is in the private address range 10.0.0/24, which cannot be routed on the Internet. An upstream network address translation (NAT) gateway or a proxy server provides access to and from the Internet.


You might use the following configuration in /etc/haproxy/haproxy.cfg on the server:

global
    daemon
    log 127.0.0.1 local0 debug
    maxconn 50000
    nbproc 1

defaults
    mode http
    timeout connect 5s
    timeout client 25s
    timeout server 25s
    timeout queue 10s

# Handle Incoming HTTP Connection Requests
listen  http-incoming
    mode http
    bind 10.0.0.10:80
# Use each server in turn, according to its weight value
    balance roundrobin
# Verify that service is available
    option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www
# Insert X-Forwarded-For header
    option forwardfor
# Define the back-end servers, which can handle up to 512 concurrent connections each
    server websvr1 192.168.1.71:80 weight 1 maxconn 512 check
    server websvr2 192.168.1.72:80 weight 1 maxconn 512 check

This configuration balances HTTP traffic between the two back-end web servers websvr1 and websvr2, whose firewalls are configured to accept incoming TCP requests on port 80.

After implementing simple /var/www/html/index.html files on the web servers and using curl to test connectivity, the following output demonstrate how HAProxy balances the traffic between the servers and how it handles the httpd service stopping on websvr1:

$ while true; do curl http://10.0.0.10; sleep 1; done
This is HTTP server websvr1 (192.168.1.71).
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr1 (192.168.1.71).
This is HTTP server websvr2 (192.168.1.72).
...
This is HTTP server websvr2 (192.168.1.72).
<html><body><h1>503 Service Unavailable</h1>
No server is available to handle this request.
</body></html>
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr2 (192.168.1.72).
...
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr1 (192.168.1.71).
This is HTTP server websvr2 (192.168.1.72).
This is HTTP server websvr1 (192.168.1.71).
...
^C
$

In this example, HAProxy detected that the httpd service had restarted on websvr1 and resumed using that server in addition to websvr2.

By combining the load balancing capability of HAProxy with the high availability capability of Keepalived or Oracle Clusterware, you can configure a backup load balancer that ensures continuity of service in the event that the master load balancer fails. See Section 16.10, “Making HAProxy Highly Available Using Keepalived” and Section 16.12, “Making HAProxy Highly Available Using Oracle Clusterware”.

See Section 16.2, “Installing and Configuring HAProxy” for details of how to install and configure HAProxy.