Load Balancing: Keeping Your Site Up
The difference between scaling and high availability, how a load balancer spreads visitors across servers and avoids failed ones, the ALB, NLB and GWLB types, and a hands-on where you watch the balancing happen.
- Key idea
- Definition
- When to use
- Caution
In this article
So far, every experiment has used a single server. That has two problems: if it fails your whole site goes down, and if visitors increase it can't serve them. This section solves both, starting with the key piece: the load balancer.
Scaling and high availability
Two terms that come up constantly and often get mixed up:
| Concept | Meaning | Example |
|---|---|---|
| Vertical scaling | A bigger server | From t3.micro to m7i.xlarge |
| Horizontal scaling | More servers | From one server to five |
| High availability | The application lives in more than one place, so it survives losing one | Servers in two Availability Zones |
Vertical scaling is simple, but it has a ceiling, usually means stopping the server, and doesn't protect you from failures. That's why modern web applications rely on horizontal scaling across Availability Zones: it gives you capacity and protection together. But something has to spread visitors across those servers.
What a load balancer does
A load balancer receives every request and passes it to the servers behind it. On AWS the service is ELB (Elastic Load Balancing), and it's fully managed: AWS runs it, scales it and keeps it available.
What you get:
- One entry point: a single domain name, however the servers behind it change.
- Health checks: it detects a failed server and stops sending it traffic.
- Spread across Availability Zones: so losing a zone doesn't stop the application.
- TLS termination: it handles the HTTPS certificate instead of each server.
- Server isolation: your servers are no longer directly exposed to the internet.
Types of load balancer
| Type | Works on | Choose it when |
|---|---|---|
| ALB (Application) | HTTP and HTTPS | Websites and APIs, with routing by path or domain. The default choice |
| NLB (Network) | TCP, UDP and TLS | You need very high performance and low latency, or a fixed IP address |
| GWLB (Gateway) | Network packets (IP) | Passing traffic through third-party security appliances such as firewalls |
There's also an old type called Classic Load Balancer. Don't use it on anything new.
How an ALB routes requests
An ALB understands the content of a request, which is what sets it apart. It's made of:
- Listener: receives traffic on a port, such as 443.
- Rules: route by path (
/api/*), domain (shop.example.com) or headers. - Target group: the targets that receive the request: EC2 servers, containers, Lambda functions or IP addresses.
So example.com/api can go to one service and example.com/images to another, through one load balancer.
Health checks
Every so often, the load balancer sends a request to each target on a path you choose, such as /health. If it fails several times in a row, the target is marked unhealthy and stops receiving traffic; once it recovers, traffic resumes automatically.
Keep the check path light, but make it reflect the application's real state. A static page that returns 200 even when the database is down won't reveal the problem.
The right security groups
Learn this pattern, because it shows up in every application: servers accept traffic only from the load balancer.
| Security group | Inbound rule | Source |
|---|---|---|
| Load balancer | 80 and 443 | Anywhere (0.0.0.0/0) |
| Servers | 80 | The load balancer's security group |
This way nobody can reach a server directly and bypass the load balancer, even if they know its address.
HTTPS and certificates
You attach a TLS certificate to the load balancer, most easily from AWS Certificate Manager, which issues public certificates for free and renews them automatically. The load balancer receives encrypted requests and handles decryption instead of each server. You'd usually add a rule redirecting all HTTP to HTTPS.
You can also host several domains with different certificates on one load balancer, thanks to SNI, which tells it which domain the browser is asking for.
Settings worth knowing
- Sticky sessions: keep a visitor on the same server using a cookie. Useful if the session is stored on the server, but they upset the balance. It's better to store sessions off the server, which we'll reach in the databases section.
- Cross-zone load balancing: spreads requests evenly across all servers regardless of their Availability Zone. On by default for ALB with no transfer charge, off by default for NLB and GWLB.
- Deregistration delay: when you remove a server, the load balancer stops sending it new requests and gives current ones time to finish, 300 seconds by default. Reduce it if your requests are short.
Hands-on: watch the balancing happen
We'll run two servers in different Availability Zones and put an ALB in front of them.
- Servers: launch two servers following part three with the same User Data, each in a different Availability Zone. The page shows the server's name, which is what we'll use.
- Target group: in EC2, open Target Groups, then Create target group. Choose Instances and HTTP on port 80, leave the health check path as
/, and register both servers. - Load balancer security group: create a group allowing HTTP from anywhere.
- Load balancer: from Load Balancers, choose Application Load Balancer, Internet-facing, select both Availability Zones, attach the security group, and point the listener on port 80 at the target group.
- Servers: edit their security group so HTTP is accepted only from the load balancer's security group.
Wait for the targets to show healthy, then copy the DNS name from the load balancer's page:
# Repeat the request and watch the server name change
for i in 1 2 3 4 5 6; do
curl -s http://YOUR-LOAD-BALANCER-DNS-NAME
echo
done
You'll see two names taking turns. Now the important test: stop one of the servers and run it again. Once the health check spots the failure, all requests go to the remaining server, and the site never went down. That's high availability.
Try opening a server's IP address directly in your browser too: the request hangs and times out, because the security group accepts traffic only from the load balancer.
Summary
- Horizontal scaling across Availability Zones gives you capacity and protection together.
- ALB is the default for the web, NLB for high performance and a fixed IP, GWLB for security appliances.
- Health checks remove a failed server automatically.
- Let servers accept traffic only from the load balancer's security group.
- Certificates from ACM are free and renew themselves.
Test yourself
Before you move on, try these questions to check you've got this part. Each one is a practical scenario, and the explanation appears once you answer.
Question 1 of 5
A company runs its /api and /images paths as two separate services, and wants them behind one domain over HTTPS. Which solution meets this with the least operational overhead?
Show the answer
Correct answer: B
An ALB understands the content of HTTP requests, so one listener can send each path to its own target group.
- A: An NLB works with connections, and doesn't read the path of a request.
- C: This one is for passing traffic through security appliances.
- D: This uses an old type, and it splits the service across two domains.
Review: How an ALB routes requests in this part, and Comparing load balancer types on the AWS site.
Question 2 of 5
A multiplayer game server communicates over UDP with very low latency. Some players' networks allow outbound traffic only to fixed IP addresses that are listed in advance. Which load balancer fits?
Show the answer
Correct answer: D
An NLB supports UDP and provides a static IP address in each Availability Zone, and you can assign your own Elastic IP addresses to it.
- A: An ALB is for HTTP and HTTPS, and its addresses aren't fixed.
- B: This one sends traffic through security appliances, and doesn't serve an application directly.
- C: This is an old type, and shouldn't be used for anything new.
Review: Types of load balancer in this part, and Elastic Load Balancing features on the AWS site.
Question 3 of 5
Servers sit behind an Application Load Balancer, but an audit finds that anyone who knows a server's public IP address can open the site directly. How should this be closed?
Show the answer
Correct answer: A
When the source of the servers' rule is the load balancer's security group, requests that come any other way don't get through, even if the address is known.
- B: Health checks watch the servers, and don't control who reaches them.
- C: This keeps a visitor on one server, and has nothing to do with direct access.
- D: Security group rules can only allow, so there's no deny rule to add.
Review: The right security groups in this part, and Security groups for your Application Load Balancer in the AWS docs.
Question 4 of 5
After an application moved behind an Application Load Balancer, its logs show only a few private addresses for all visitors. The security team needs each visitor's real IP address, with the smallest change. What should the team do?
Show the answer
Correct answer: C
The server sees the load balancer's address, because the connection comes from it. The ALB passes the visitor's real address in this header.
- A: The requests would still arrive through the load balancer.
- B: This changes how requests are spread, not the address the server sees.
- D: This would remove the load balancer and its protection against failures.
Review: How an ALB routes requests in this part, and X-Forwarded headers in the AWS docs.
Question 5 of 5
An application keeps user sessions in each server's memory. After it moved to several servers behind an Application Load Balancer, users started getting signed out at random. Which two changes solve this? (Choose two.)
Show the answer
Correct answer: B + D
Each server only knows its own sessions. Stickiness keeps a visitor on the same server, and a shared cache makes the session available to every server. The cache is the better design, because sessions survive when a server disappears.
- A: This spreads requests more evenly, and could still send a visitor to a different server.
- C: This concerns requests in progress on a server being removed.
- E: This only delays spotting failed servers.
Review: Settings worth knowing in this part, and Target group attributes and Make services stateless in the AWS docs.
But our number of servers is still fixed, and you're the one launching them by hand. In part seven we'll have AWS add and remove them on its own, and bring everything we've learned together into a full application.