Author: Francis NdunguLast Updated: Thu, Sep 9, 2021
HAProxy stands for High Availability Proxy. It's an open-source load balancer that you can use to distribute HTTP traffic to multiple backend applications, websites, or databases to create a highly available system. It is the fastest and most superior load balancer that offers massive scalability in any environment, making it the number one choice for high-profile websites like Twitter, GitHub, and Amazon Web Service.
In this age of an internet-connected world, your application might be serving millions of users around the globe(For instance, a social media application). In such a mission-critical system, any downtime may lead to financial loss and an unpleasant customer experience. To ensure that your application works even when some of its components fail, you should create multiple instances of your computing infrastructure and put a customer-facing load balancer to route traffic to the clustered environment.
HAProxy allows your system to tolerate interruptions with no downtime to users. To use the technology, you should design your system with redundancy in mind. That is, you should run multiple instances of computer components that are very likely to fail or require periodic maintenance. Also, HAProxy failover mechanism uses different performance metrics to monitor the availability and health of the redundant servers working as a group to switch traffic only to active components. Therefore, HAProxy meets all the basic elements of high availability. That is redundancy, failover, and monitoring.
In this guide, you'll install and configure the HAProxy load balancer on Ubuntu 20.04 server to distribute web traffic to two different servers.
To follow along with this HAProxy tutorial, you require the following:
A set of 3 Ubuntu 20.04 servers configured with private networking. Please refer to the guide on How to Create a Private Network to set up private networking for your Vultr servers. Your servers should be in the same location.
A sudo user.
This guide uses the following public/private IP addresses and hostnames for the servers. Make sure to change the values accordingly.
Public IP: 192.0.2.10
Private IP: 10.0.0.10
Public IP: 192.0.2.11
Private IP: 10.0.0.11
Public IP: 192.0.2.12
Private IP: 10.0.0.12
Ensure Apache webserver is only installed on server-1 and server-2. Don't install Apache on the main-server because there will be a port conflict. This is because Apache listens on the same port (80) as HAProxy.
In this step, you'll pull the HAProxy package from the official Ubuntu software repository. SSH to your server and update the package information index by running the command below.
$ sudo apt update
Next, issue the following command to install the
$ sudo apt install -y haproxy
Check the status of the HaProxy server.
$ sudo systemctl status haproxy
Ensure the HaProxy service is running by confirming the following output.
... Active: active (running) ...
To check your HaProxy version, run the following command.
$ haproxy -v
Ensure you get the version number displayed as shown below.
HA-Proxy version 2.0.13-2ubuntu0.2 2021/08/16 - https://haproxy.org/
After installing the HAProxy package, you'll configure it next to distribute traffic to the rest of your servers.
HAProxy maintains a configuration file at the following location.
First, back up the file using the Linux
cp command to ensure you can revert to the default settings if you make any mistakes.
$ sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.bk
Next, use the
nano text editor to open the file for editing purposes.
$ sudo nano /etc/haproxy/haproxy.cfg
Once opened, the HAProxy configuration file is divided into different sections, which play a vital role, as explained below.
global: At the top, HAProxy contains system-wide settings that mainly deal with security and performance tuning. For now, don't change these values. Here are some of the global settings.
global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners stats timeout 30s user haproxy group haproxy daemon # Default SSL material locations ca-base /etc/ssl/certs crt-base /etc/ssl/private ...
defaults: The defaults holds some settings that you would probably use without further customizations, including error reporting and timeout configurations. The settings may be similar to the following output. Don't touch these settings; you'll run HAProxy with the default values for now.
defaults log global mode http ... timeout server 50000 errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http ... errorfile 408 /etc/haproxy/errors/408.http
frontend and backend: In addition to the global and defaults settings HAProxy allows you to define some frontend and backend settings. In this guide, you're using HAProxy as a reverse proxy in front of two backend servers. Therefore, you should define both the frontend and backend settings as shown below.
In the frontend, instruct HaProxy to bind to port 80(
bind *:80) and forward traffic to a backend section which you've named
web_servers. In the backend section, set HAProxy to use the
roundrobin algorithm to select every backend server cyclically without any preference. You may also use the
leastconn algorithm to prioritize the server with the least active connections. Next, define the IP address and ports of the servers where you want the traffic to be distributed. Remember to replace the IP addresses
10.0.0.12 with the appropriate private IP addresses of your nominated backend servers. The
check parameter validates the health of the server before routing any clients to it.
frontend example_front_end bind *:80 option forwardfor default_backend web_servers backend web_servers balance roundrobin server server-1 10.0.0.11:8080 check server server-2 10.0.0.12:8080 check
listen: Optionally, define some statistical settings on a new listen section as shown below. The settings will help you log in to the HAProxy server on a web browser and view the performance of your servers. Replace
ha_proxy_admin with an appropriate username. Change
EXAMPLE_PASSWORD with a strong value.
listen stats bind :32600 stats enable stats uri / stats hide-version stats auth ha_proxy_admin:EXAMPLE_PASSWORD
Save and close the
/etc/haproxy/haproxy.cfg when you're through with editing. In the above settings, you've instructed HAProxy to listen on port 80. In case you've Apache web server installed on the main-server, it will still listen on the same port(80), and there will be a conflict, and HaProxy won't be able to load. Therefore, stop the Apache webserver using the following command in case you've it.
$ sudo systemctl stop apache2
You can now gracefully restart HAProxy to load the new configuration settings using the following command.
$ sudo systemctl restart haproxy
The HAProxy server is now ready to listen for HTTP traffic and route it to the appropriate backend servers. In the next step, you'll configure the Apache webserver on the backend servers.
By default, the Apache web server listens for HTTP traffic on port 80. In the previous section, you've configured your HAProxy server to direct traffic to port 8080 on the backend servers. In this step, you'll configure the same on these two servers.
/etc/apache2/ports.conf file on both
server-2 on different terminals using
nano text editor.
$ sudo nano /etc/apache2/ports.conf
Locate the following
Then, change the port from
8080 as shown below on both backend servers.
Still, on both the backend servers, open the virtual host file below.
$ sudo nano /etc/apache2/sites-available/000-default.conf
Locate the line below.
<VirtualHost *:80> ...
Change the value of
<VirtualHost *:8080> ...
Restart Apache on both servers to load the new changes.
$ sudo systemctl restart apache2
Apache webserver should now listen for incoming traffic on port
8080 on both the backend servers as soon as it's forwarded by the HAProxy server. In the next step, you'll create some web content on the backend servers.
Clients will send HTTP requests to the main server where you've installed HAProxy. Then, HaProxy will route the traffic in a balanced way to the backend servers. Therefore, you should create some web content on the public root directories of server-1 and server-2.
First, delete the default
/var/www/html/index.html files on both the backend servers.
$ sudo rm /var/www/html/index.html
$ sudo rm /var/www/html/index.html
Next, open a new HTML file on server-1.
$ sudo nano /var/www/html/index.html
Then, enter the content below into the
/var/www/html/index.html on server-1.
<html> <head> <title>Backend Server 1</title> </head> <body> <h1>Server 1 is working.</h1> </body> </html>
Save and close the file. Next, create a new
/var/www/html/index.html on server-2.
$ sudo nano /var/www/html/index.html
Then enter the information below into the
/var/www/html/index.html file on server-2.
<html> <head> <title>Backend Server 2</title> </head> <body> <h1>Server 2 is working.</h1> </body> </html>
Save and close the file. You've now created different web content in the backend servers. In the next step, you'll test whether HAProxy can route and distribute traffic to your backend servers.
In your web browser, enter the public IP address or domain name of the main-server where you installed HAProxy.
You should receive the response below when you visit the page for the first time showing you have connected to backend server-1.
Refresh the page, and this time around, you should view the content of backend server-2.
To view general statistical information about your frontend and backend servers, visit the HaProxy's server public IP address on port
Enter the login details that you defined on the stats sections in the HAProxy configuration file. For instance
username:ha_proxy_admin, password:EXAMPLE_PASSWORD to log in.
... listen stats ... stats auth ha_proxy_admin:EXAMPLE_PASSWORD ...
You should see a dashboard with a lot of HAProxy information.
Your HAProxy server is working as expected, and indeed, you're redistributing the load from the main server to the backend servers as you had expected. In this guide, you've created two different web pages with varying content to prove the load-distribution concept. In a production environment, the contents on the redundant servers should be similar, or if you're fetching data from a database, the backend servers should display the same data. For instance, the backends should connect to a MySQL group replicated database. This helps your app to tolerate downtimes in case some of the backend servers fail.
In this tutorial, you've installed HAProxy on Ubuntu 20.04 and successfully distributed HTTP traffic to two different backend servers. You can extend the logic in this guide and even set up more redundant servers depending on your application load. HAProxy allows you to distribute traffic on your clustered environment to avoid overwhelming a single server when thousands of clients are connected to your application.