Load Balancing with HAProxy: A Beginner's Guide

Load Balancing with HAProxy: A Beginner's Guide

What is HAProxy

HAProxy is a high-performance open-source load balancer and proxy server that enables the scaling of web applications by distributing traffic across multiple servers. It is designed to handle high traffic volumes and improve the availability and reliability of web applications.

One of the key features of HAProxy is its ability to perform load balancing across multiple servers. It can distribute incoming traffic to the most suitable server based on various algorithms, such as round-robin, least connections, and IP hash. This ensures that traffic is evenly distributed across servers and that no single server is overwhelmed with traffic.HAProxy also offers high availability features such as health checks, which monitor the status of the backend servers, and automatic failover, which redirects traffic to an available server if one goes down. This ensures that the application remains available and responsive to users even if a server fails.

In addition to load balancing and high availability, HAProxy provides advanced traffic management features such as SSL termination, content switching, and request routing based on URL paths and HTTP headers. These features enable the application to handle complex traffic scenarios and optimize performance.HAProxy is widely used in production environments to handle large amounts of traffic and provide high availability and reliability for web applications. It is commonly used in industries such as e-commerce, finance, and media, where the ability to handle high traffic volumes is critical for business success.


Installation and Configuration of HAProxy

In this guide, we'll walk through the steps to install and configure HAProxy on a Linux server.

Step 1: Install HAProxy The first step is to install HAProxy on your server. The installation process varies depending on your Linux distribution. Here's how to install HAProxy on Ubuntu.

sudo apt-get update
sudo apt-get install haproxy

Step 2: Configure HAProxy Once HAProxy is installed, you need to configure it. Create a config file test.cfg.

touch test.cfg

Let's pause this for now. we'll write the code bit later


Understanding Layer 4 and Layer 7 Load Balancing in HAProxy

In HAProxy, layer 4 load balancing is used to distribute traffic based on the IP address and port numbers of the incoming connection. Layer 4 load balancing works at the transport layer of the OSI model and can balance both TCP and UDP traffic.

On the other hand, layer 7 load balancing is used to distribute traffic based on the content of the incoming HTTP requests. Layer 7 load balancing works at the application layer of the OSI model and can balance HTTP and HTTPS traffic. It can also perform content switching based on different URLs, HTTP headers, cookies, and other factors.

In general, layer 4 load balancing is faster and more efficient than layer 7 load balancing because it requires less processing and can handle a larger volume of traffic. However, layer 7 load balancing provides more granular control and can be used to balance traffic based on more complex criteria. The choice between layer 4 and layer 7 load balancing depends on the specific needs of the application and the desired balance between performance and functionality.

  • Layer 4 Load Balancing: A Layer 4 reverse proxy in HAProxy is a type of load balancer that distributes incoming traffic among multiple servers based on the source IP address and port number of the incoming request.

    In simple terms, when a client sends a request to the load balancer, the load balancer examines the source IP address and port of the request and uses this information to determine which server in the backend pool should handle the request.

    Layer 4 load balancing does not examine the contents of the request itself, so it is a faster and more efficient way of load balancing compared to Layer 7 load balancing.

    To configure Layer 4 load balancing in HAProxy, you would typically define a frontend section with a listener on a specific port, and one or more backend sections with a list of servers to distribute traffic to. You can also configure the load balancing algorithm to use, such as round-robin, least connections, or IP hash.

Let's consider an example scenario where two backend servers are running on ports 3000 and 3001, and a client needs to access them through a load balancer. We can use HAProxy to implement layer 4 load balancing.

In this scenario, the client sends a request to the load balancer, which then forwards the request to one of the backend servers based on the load-balancing algorithm used. The backend server processes the request and sends the response back to the client through the load balancer.

The load balancer keeps track of the connections and can distribute the load among the backend servers based on various algorithms, such as round-robin, least connections, or IP hash.

For instance, if we use the round-robin algorithm, the first request from the client will go to the first backend server on port 3000. The second request will go to the second backend server on port 3001, and so on.

Overall, layer 4 load balancing helps to distribute the traffic evenly across multiple backend servers, thus improving performance, availability, and reliability.

here's a configuration for a layer 4 load balancing setup for the above example:

# Define the front-end configuration
frontend myapp
    bind *:80
    mode tcp

    # Define the back-end servers
    default_backend servers

# Define the back-end configuration
backend servers
    mode tcp
    balance roundrobin

    # Define the servers
    server server1 localhost:3000 check
    server server2 localhost:3001 check

In this configuration, the frontend section defines the front-end configuration with myapp as the name. The bind option specifies the IP address and port to listen on, and mode tcp specifies that the traffic will be TCP traffic.

The backend section defines the back-end configuration with servers as the name. The mode tcp option specifies that the traffic will be TCP traffic. The balance roundrobin option specifies that traffic will be distributed evenly among the servers.

The server lines define the back-end servers, with server1 and server2 as the server name, localhost:3000 and localhost:3001 as the IP addresses and port numbers of the servers, and check to indicate that the servers should be health-checked before traffic is sent to them.

  • Layer 7 Load Balancing: In simple words, a layer 7 reverse proxy is a type of load balancer that operates at the application layer of the OSI model. This means that it can inspect and make decisions based on application-level data such as HTTP headers, cookies, and URLs.

    HAProxy as a layer 7 reverse proxy can route incoming requests based on various criteria such as the path or domain name of the request. For example, it can route all requests to /api/* to one set of backend servers and all other requests to another set of backend servers.

    Layer 7 reverse proxies can also perform various application-related tasks such as SSL termination, content caching, and compression. For example, HAProxy can offload SSL decryption from backend servers and cache static content to improve performance.

    Overall, layer 7 reverse proxies provide more advanced features and greater flexibility compared to layer 4 load balancers, making them suitable for more complex applications and environments.

global
    maxconn 1000
    mode tcp


frontend http80
    bind *:8080
    mode http
    timeout client 60s
    acl app1 path_end -i /get-user
    acl app2 path_end -i /create-user
    use_backend read_servers if app1
    use_backend write_servers if app2
    default_backend allservers


backend read_servers
    timeout connect 10s
    timeout server 10s
    mode http
    # balance source
    # balance roundrobin
    # balance leastconn
    # balance source
    balance uri
    hash-type consistent
    server server2222 127.0.0.1:3000
    server server3333 127.0.0.1:3001

backend write_servers
    timeout connect 10s
    timeout server 10s
    mode http
    # balance source
    # balance roundrobin
    # balance leastconn
    # balance source
    balance uri
    hash-type consistent
    server server4444 127.0.0.1:4000
    server server5555 127.0.0.1:4001

backend allservers
    timeout connect 10s
    timeout server 10s
    mode http
    server server2222 127.0.0.1:3000
    server server3333 127.0.0.1:3001
    server server4444 127.0.0.1:4000
    server server5555 127.0.0.1:4001

The maxconn setting in the global section of the HAProxy configuration.which limits the number of concurrent connections that HAProxy can handle across all frontend and backend connections. The code example above sets maxconn to 1000, meaning that the maximum number of concurrent connections across all connections is 1000. If this limit is reached, new connections will be rejected until the number of concurrent connections drops below this limit.

When processing requests from a connection, certain operations are more resource-intensive than others. For example, parsing request or response headers is less costly than forwarding data, and establishing or closing a connection to a server is less costly than parsing headers. A TLS resume operation is less costly than establishing or closing a connection, while a full TLS handshake with a key computation is less costly than a TLS resume operation. A connection with data in its buffers costs less CPU than an idle connection, and a connection with data in its buffers also costs less memory than a TLS context.

There is a frontend http80 that listens on port 8080 and handles HTTP traffic. It defines two ACLs - app1 for the endpoint "/get-user" and app2 for the endpoint "/create-user". It uses the use_backend directive to forward requests to the appropriate backend server based on the ACLs matched.

For ACL app1, it forwards requests to the read_server backend that balances traffic between two servers running on ports 3000 and 3001. For ACL app2, it forwards requests to the write_server backend that balances traffic between two servers running on ports 4000 and 4001.

There is also a default_backend directive that routes traffic to the allservers backend, which contains all the backend servers defined. The allservers backend is used when no ACLs match or when there is an error in the configuration.

The load balancing algorithm used for read_server and write_server is URI-based, and the hash type is consistent. This ensures that requests with the same URI are always forwarded to the same backend server. The timeout directives define the maximum time allowed for connections to be established and for servers to respond.

Overall, this configuration provides layer 7 load balancing based on the URI of the requests and ensures that the requests are forwarded to the appropriate backend server based on the URI path.

Extra: There are other load-balancing algorithms which are commented on in the above code

  1. balance roundrobin: This algorithm distributes traffic evenly across all servers in a backend in a round-robin fashion. Each new connection is sent to the next server in the list, and the order is repeated once all servers have been used. This is a good default algorithm for most cases, as it ensures that all servers are utilized equally.

  2. balance source: This algorithm uses the client's IP address to determine which server to send the traffic to. This can be useful if you want to ensure that requests from the same client are always sent to the same server, such as in a session-based application.

  3. balance leastconn: This algorithm sends traffic to the server with the least number of connections, which can be useful in applications where some requests take longer to process than others. By sending requests to the server with the least number of connections, this algorithm can help ensure that all servers are working at roughly the same capacity.

You can check out my project related to haproxy here

Summary

The blog discusses the HAProxy, an open-source load balancer and proxy server that helps distribute traffic across multiple servers. HAProxy has various features such as load balancing, high availability, SSL termination, content switching, and request routing based on URL paths and HTTP headers, making it suitable for large amounts of traffic and providing high availability and reliability for web applications. The blog also explains the installation and configuration of HAProxy on Linux servers, along with the differences between layer 4 and layer 7 load balancing in HAProxy.