Compare and Troubleshoot ALBs and NLBs in AWS
Part Three — HTTP Request Based Routing (ALB only) and Overall Comparison
In this series of blog posts, I first examined ALB and NLB performance differences in Part 1. Then I explored how each ELB works in Part 2. In this series’ third and final blog post, I will cover a key advantage of using ALB. Let’s look at how ALB can direct traffic at layer 7.
In the ALB console, you can see several different routing conditions:
We’re going to now check out each of these conditions experimentally. I have set up the same ALB from Post 1 and Post 2 of the series, but this time with two target groups, each with one target in it. This one target group will be our default or catch-all target group. The other will be a test for our condition rule.
Host Header Based Routing
We’re going to turn our attention to how a host header, and its close relative, the HTTP header, work.
When we run an HTTP request using curl, a web browser, or any other tool, an HTTP host header (and often other headers) is always included. Here’s a request to http://google.com below:
You can see that curl includes a header with a key of “Host.”
Examining at this interaction from a packet perspective, you see:
The TCP three-way handshake is completed with the server. Then an HTTP GET request is sent. The host header (and others) are included in the GET request in packet number 4. Headers are not exclusive to GET requests and apply to other HTTP verbs such as PUT, PATCH, etc.
Bringing this back to my ALB, I set one host header rule to match for “my-website.com” and direct this traffic to Target Group 2. My default rule directs traffic to Target Group 1:
When I run a default curl request to the ALB, it specifies its own hostname in the host header;
To test if my condition is working, I sent a request to the ALB with the host header of “Host:my-website.com”:
This time the request went through to Target Group 2 as our host header condition matched.
If I try with any other host header, I’m directed to my default target group as per this request with a host header of “not-my-website.com”:
Host headers do not effect the DNS query of the local device. Their primary function is to separate out different domain names so you can host multiple services, like websites, behind a single ALB.
HTTP Header Based Routing
HTTP header-based routing is closely related to host header routing. We can include any header we want in an HTTP header. I’m going to show you another curl so you can see how I define the custom header:
Here’s a packet capture of the above curl:
As seen previously, there is always the TCP three-way handshake with the remote server, and then the HTTP GET request. In this GET request, notice that there are three standard headers and the one I defined myself, “my-custom-header:alpha”.
To test how this works in an ALB, I created three target groups and directed traffic as per below:
Default http headers → Default Target group
"User-Group:alpha" header → Target Group 1
"User-Group:beta" header → Target Group 2
You can see more of my ALB header-based routing setup and testing results in this short video.
Check out how I specified the headers in the curl requests and how the ALB conditions directed each request to the specific target groups.
Path Based Routing
Moving on, we’ll now examine how to define a path in a request to Google and what this looks like at a packet level.
The packet capture of the above exchange looks like this:
To test how my ALB distributed requests with different paths, I modified my previously defined ALB header rules to instead distribute based on the following paths:
Here’s a video that demonstrates how to run a variety of path-based requests and how to test which target group the requests are routed to.
Routing by HTTP Method, Query String, and Source IP
In the video below, I’ve added a few more rules to my ALB to show you how to create requests that hit each rule.
Notice exactly where the request method and the query are located in the HTTP request. If I send a dummy request to Google,
and look in my packet capture of this interaction,
you can see above precisely what the ALB is routing traffic based on. This application layer distribution ability is only offered by ALB. If HTTP distribution was required for your application, ALB would be your choice over NLB.
What Can’t the NLB See?
NLBs can only see up to layer 4, transmission control protocol. So they cannot route traffic based on any of the ALB filters discussed above.
We can see this if we examine the same packet from above.
Overall Comparison (TLDR)
Based on the testing I’ve done in this series of blog posts, here’s how I would summarize the advantages of each ELB flavor:
- NLB does not need to scale. ALB does, and it requires about three minutes to do so. This means for very spikey workloads where scaling extremely quickly is required, NLB may be a better choice. See Part 2 of this series for more detail.
- Due to ALB scaling, the ALB requires IP changes. Whereas NLB can, theoretically, retain the same IPs for its lifetime. If you require stable IPs for your use case, NLB may be a better choice. See Part 2 of this series for more detail.
- ALB can route traffic to backend targets based on various HTTP application layer properties. Where this is required, ALB may be a better choice (covered earlier in this post).
- If you have a client/server that is sending large GET/PUT data streams, NLB may be your better choice. See Part 1 of this series for more on this.
- ALB can only listen on HTTP(/s) protocol. If your application is using another protocol, you will need to use an NLB to pass through to your backends.
- Due to WAF (Web Application Firewall) operating in the application layer, it is not supported by NLB. You can attach your ALB to a WAF for security. ALB would be your choice if you have a hard requirement for WAF security.
Conclusion
I hope the information we have been through in this blog post series has helped you compare the two most common AWS ELB types. I have spent many hours as an ELB user and with customers trouble shooting specific aspects of their operations. With the visuals I’ve included in each of the examples above, you are not only better equipped to pick which best suits your use case, but to troubleshoot some of the common issues you might come across. Happy Load Balancing!