Configuring Round Robin Load Balancing by Using HAProxy

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

The following figure shows an HAProxy server (10.0.0.10), which is connected to an externally facing network (10.0.0.0/24) and to an internal network (192.168.1.0/24). Two web servers, websrv1 (192.168.1.71) and websrv2 (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.0/24, which can't be routed on the Internet. An upstream Network Address Translation (NAT) gateway or a proxy server provides access to and from the Internet.

Figure 2-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.0/24) and to an internal network (192.168.1.0/24). Two web servers, websrv1 (192.168.1.71) and websrv2 (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.0/24, which can't be routed on the Internet. An upstream NAT gateway or a proxy server provides access to and from the Internet.
  1. Update the configuration on the HAProxy server.

    The following is an example configuration in /etc/haproxy/haproxy.cfg on the server:

    global
        daemon
        log 127.0.0.1 local0 debug
        maxconn 50000
        nbthread 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 
        http-check send meth HEAD ver HTTP/1.1 hdr Host www
    # Insert X-Forwarded-For header
        option forwardfor
    # Define the back-end servers, which can handle up to 512 concurrent connections each
        server websrv1 192.168.1.71:80 maxconn 512 check
        server websrv2 192.168.1.72:80 maxconn 512 check

    This configuration balances HTTP traffic between the two backend web servers websrv1 and websrv2, whose firewalls are configured to accept incoming TCP requests on port 80. The traffic is distributed equally between the servers and each server can handle a maximum of 512 concurrent connections. A health-check is also configured and this performs a request for the HTTP headers on a request for the web root on each backend server.

  2. Reload the HAProxy systemd service.
    sudo systemctl reload haproxy
  3. Validate that round-robin load balancing is working.

    Assuming that the web servers are each configured to serve a web page, use curl to test connectivity. You can use a while loop in the shell to repeat the test over a period. To cancel out of the loop, use the Ctrl-C key combination:

    while true; do curl http://10.0.0.10; sleep 1; done

    The following output shows how HAProxy balances the traffic between the servers and how it handles the httpd service stopping on websrv1:

    This is HTTP server websrv1 (192.168.1.71).
    This is HTTP server websrv2 (192.168.1.72).
    This is HTTP server websrv1 (192.168.1.71).
    This is HTTP server websrv2 (192.168.1.72).
    ...
    This is HTTP server websrv2 (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 websrv2 (192.168.1.72).
    This is HTTP server websrv2 (192.168.1.72).
    This is HTTP server websrv2 (192.168.1.72).
    ...
    This is HTTP server websrv2 (192.168.1.72).
    This is HTTP server websrv2 (192.168.1.72).
    This is HTTP server websrv1 (192.168.1.71).
    This is HTTP server websrv2 (192.168.1.72).
    This is HTTP server websrv1 (192.168.1.71).
    ...

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

    Note:

    In these examples the web servers are configured to serve a page that describes the web server name and IP address. The outputs in a real world configuration are likely to differ.

By combining the load balancing capability of HAProxy with the high-availability capability of Keepalived, you can configure a backup load balancer that ensures continuity of service if the primary load balancer fails. See Enhancing Load Balancing by Using Keepalived With HAProxy for more information on how this configuration can be extended.