Phase 1: Foundations

Load balancing algorithms & reverse proxies

Beginner ~3 min read
Think of it this way A friendly analogy. Read this if the technical version feels dense. Show Hide

Imagine a super popular pizza restaurant! It’s the best in town, and everyone wants to order a pizza, especially on a Friday night. If the restaurant only had one chef and one oven, what would happen? That chef would quickly get buried under hundreds of orders, get stressed, make mistakes, and pizzas would take forever to come out. Some hungry customers might even give up and leave! That's no fun for anyone.

To fix this, our smart pizza restaurant hires lots of chefs and installs many ovens. But how do they make sure orders are spread out fairly, so no single chef gets overwhelmed while another is just twiddling their thumbs? That's where a special manager, like a super-organized host at the front door, comes in. When you walk in to order a pizza, you don't shout your request directly to a chef in the back kitchen. You tell it to the host. The host then looks at all the chefs and decides which one is ready for a new order, passing your request along. This host is like a "load balancer" – they balance the "load" of work. Since the customer only ever talks to the host, and the host gets the pizza from any chef, the host is also acting as a "reverse proxy," keeping the kitchen organized behind the scenes.

How does our clever host decide which chef gets the next order? They use different "algorithms," which are just fancy words for a set of rules. A simple rule might be "Round Robin": send the first order to Chef A, the next to Chef B, then Chef C, and then back to Chef A again. This works great if all chefs are equally fast. But what if Chef A is still kneading dough for a giant party order, while Chef B just finished theirs and is ready for more? A smarter rule, like "Least Connections," would have the host send the new order to Chef B, because they currently have the fewest orders (or "connections") to work on, making sure everyone stays busy but no one gets swamped.

So, when you're building your own awesome website or a super fun online game, and lots and lots of people start using it all at once, you'll want to use these same ideas. By setting up "hosts" (load balancers) for your "chefs" (servers), you can make sure your creation can handle thousands, even millions, of users smoothly without slowing down or crashing, keeping everyone happy and engaged!

Imagine you have a popular website, and thousands of users are trying to access it simultaneously. If all these requests hit a single server, it would quickly get overwhelmed and crash. This is where load balancing comes in. A load balancer acts like a traffic cop, sitting in front of your multiple application servers and distributing incoming network requests across them. This not only prevents any single server from becoming a bottleneck but also improves overall responsiveness and availability. A reverse proxy is a specific type of load balancer that retrieves resources on behalf of a client from one or more servers. It's the server-side counterpart to a forward proxy, providing an additional layer of abstraction and control over incoming traffic.

To decide which server gets a request, load balancers use various algorithms. The simplest is Round Robin, which cycles requests sequentially among servers (server 1, then server 2, then server 3, and so on). This works well when all your servers have similar processing power and handle similar workloads. For more dynamic environments, Least Connections is often preferred; it directs new requests to the server with the fewest active connections, ensuring busy servers aren't overloaded further. Another useful one is IP Hash, where the client's IP address determines which server they are sent to, which can be great for maintaining "sticky sessions" where a user consistently interacts with the same backend server.

For an SRE, understanding load balancers and reverse proxies is fundamental. They are critical components for building resilient and scalable systems. They enable you to seamlessly add or remove backend servers without affecting users, perform maintenance with zero downtime by routing traffic away from specific servers, and protect your application servers by handling tasks like TLS/SSL termination (decrypting traffic) at the proxy level. Effectively configuring and monitoring these systems is key to ensuring your services remain highly available and performant, even under heavy load or during outages.

Key Takeaways

  • Load balancers distribute incoming traffic across multiple servers to prevent overload and improve performance and availability.
  • A reverse proxy is a type of load balancer that sits in front of your backend servers, managing client requests and providing an abstraction layer.
  • Common load balancing algorithms include Round Robin (sequential distribution) and Least Connections (sends to the least busy server).
  • SREs use these tools for high availability, scalability, graceful degradation during failures, and seamless maintenance operations.
  • They can also handle tasks like TLS termination and traffic filtering, enhancing security and efficiency.

Code Example

nginx
http {
    upstream backend_servers {
        # Round Robin is the default algorithm
        server backend1.example.com;
        server backend2.example.com;
        server backend3.example.com;
        # For Least Connections:
        # least_conn;
    }

    server {
        listen 80;
        server_name myapp.com;

        location / {
            proxy_pass http://backend_servers;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}

How this code works

This Nginx configuration sets up a reverse proxy that acts as a load balancer, distributing incoming web requests across multiple application servers to handle traffic efficiently. The upstream backend_servers block defines a logical group of these servers, listing backend1.example.com, backend2.example.com, and backend3.example.com. A subtle but important detail here is that Nginx, by default, uses the Round Robin load balancing algorithm: it cycles through these servers, sending each new request to the next server in the list, ensuring an even distribution of traffic without any explicit configuration. To use a different strategy, like Least Connections, one would uncomment the least_conn; directive within this block.

The subsequent server block is responsible for listening for incoming web requests on listen 80 for the specified server_name myapp.com. Inside its location / block, the proxy_pass http://backend_servers; directive forwards all incoming requests to the group of backend servers defined earlier, with Nginx managing the load distribution. The proxy_set_header lines are essential for passing original client information, like the Host and the client's IP address (X-Real-IP, X-Forwarded-For), to the backend application servers, which is crucial for proper logging and application functionality.