Content Switching
Content-switching is an OSI layer 7 application switching technique, which in lamans terms means that it has access to the HTTP requests and responses of your application. By inspecting each request and response, it make decision on where to send those requests and how to handle responses.
HAProxy is an open source load balancing tool that also has the ability to implement content switching.
Proxies & Reverse Proxies
You might be familiar with a Proxy, which is basically something that sits between the client and the server. When the client makes a request it first goes through the proxy then to the server. The response from the server then goes back through the proxy to the client. These are usually implemented by the client and completely transparent to the server. A great example of this is when someone configures their browser to use a proxy to access the internet, with a tool such as Tor.
A Reverse Proxy is the same thing except it acts on behalf of the server. One example of a Reverse Proxy is a load balancer, which receives requests from a users and usually proxies them to one of several backend servers. This process is completely transparent to the client. Content switching is also a form of Reverse Proxy.
Example Scenario
Let’s say you’re in charge of a large social bookmarking application, http://delicioso.com. The shelf life for that system has come to and end and you’re team has decided to rewrite everything in Rails. It’s going to take a long time to migrate everything over to the new application, and you want to reduce the risk involved with a huge release cycle. Instead you want to take an agile approach and roll out bits and pieces over time in the following order:
- Configure HAProxy as a Reverse Proxy
- Phase in user profiles – http://delicioso.com/profile/…
- …
For the purpose if this example, let’s call the current application Legacy. Image your current infrastructure is setup like the following:
+-------------------+
| example.com |
User +----------> |-------------------|
| legacy:80 |
+-------------------+
Step 1: Configure HAProxy as a Reverse Proxy
The first step is to setup HAProxy to be reverse proxy for Legacy, so later we can implement content-switching. You’ll need to have HAProxy installed.
+-------------------+
| example.com |
User +----------> |-------------------|
| HAProxy:80 |
| legacy:8001 |
+-------------------+
Here’s the config file to configure HAProxy in this way:
global
#debug # uncomment to enable debug mode for HAProxy
defaults
mode http # enable http mode which gives of layer 7 filtering
timeout connect 5000ms # max time to wait for a connection attempt
# to a server to succeed
timeout client 50000ms # max inactivity time on the client side
timeout server 50000ms # max inactivity time on the server side
backend legacy # define a group of backend servers
server legacy_server 127.0.0.1:8001 # add a server to this backend
frontend app *:80 # define what port to listed to for HAProxy
default_backend legacy # set the default server for all request
Step 2: Phase in User Profiles
All of your user’s profile pages have a URL format as follows: /profile/username. Your team finished implementing this in the new Rails framework and it’s time to roll it out. The rails app is running on port 8002.
+-------------------+
| example.com |
User +----------> |-------------------|
| HAProxy:80 |
| legacy:8001 |
| rails:8002 |
+-------------------+
Here’s the new config file for content-switching all requests starting with /profile to the new rails application
global
#debug
defaults
mode http
option httpclose # close the tcp connection after every request
timeout connect 5000ms
timeout client 50000ms
timeout server 50000ms
backend legacy
server legacy_server 127.0.0.1:8001
backend rails # define a group of backend servers
server rails_server 127.0.0.1:8002 # add a server to this backend
frontend app *:80
default_backend legacy
acl rails_path path_beg /profile # acl rule for rails supported paths
use_backend rails if rails_path # use rails if the rules match.
Check out the HAProxy documentation for more keywords your can use to route requests. This was a pretty simple example, this get’s more challenging when you need to handle session state across the legacy and new systems.