Routing and Load Balancing Using HAProxy

As the microservice buzzword catches up, I believe sooner or later you might think of trying microservices. In this blog post, I shall cover some of the common problems related to routing and load balancing and how to get around them using HAProxy.

Routing Using HAProxy

Imagine you have a project that creates task list for a logged in user.

I can think of two entities:

  • User
  • Task

So now you will have two services:

  • User Service
  • Task Service

Both (User/Task) provide API for basic CRUD operations. Now on the frontend, you will have API calls like this:

Microservice: 1 hosts the Task Service.

GET http://<your-machine>:8081/tasks/get

GET http://<your-machine>:8081/tasks/get/{id}

POST http://<your-machine>:8081/tasks/ + payload

PUT http://<your-machine>:8081/tasks/ + payload

…and so on.

Microservice:2 hosts the User Service.

GET http://<your-machine>:8082/users/get

GET http://<your-machine>:8082/users/get/{id}

POST http://<your-machine>:8082/users/ + payload

PUT http://<your-machine>:8082/users/ + payload

…and so on.

The problem here is, the API exposes a few things to the frontend. You are running microservices on 8081 and 8082. Thus frontend should be aware of these ports. As you go on adding more microservices, you will need to open up as many ports. For example, if there are 25 microservices, then you need to open up 25 ports!

In short, this is a routing problem.

We can get around this using a load balancer HAProxy. Here’s how:

  1. Install HAProxy, where you host your microservices.

sudo add-apt-repository -y ppa:vbernat/haproxy-1.5
sudo apt-get update
sudo apt-get install -y haproxy

  1. Post installation open /etc/haproxy/haproxy.cfg for editing.

A sample configuration will look like this.

  1. After making the configuration change, restart the HAProxy service:

sudo service haproxy restart

Here is a pictorial view of the problem and the proposed solution using HAProxy. All the ports are open for frontend to make API calls as below:

After using HAProxy:

Routing using HAProxy

Advantages of Using HAProxy

  • Frontend does not need to know which services are running at which port.
  • Only a single port needs to be open. Frontend will hit that port with the signature. HAProxy will forward it to the correct microservice using the mapping written in the configuration.

Load Balancing Using HAProxy

Imagine you have a high number of requests coming to Microservice:1 {Task Service}. Due to the number of requests, you have to do some load balancing.

  1. Spawn up a new server to host Microservice:1 {Task Service} on Machine 2. Now we have something like this:

Machine 1

Hosts

Microservice:1 {Task Service} runs on port 8081

Microservice:2 {User Service} runs on port 8082

Machine 2

Microservice:1 {Task Service} runs on port 8081

  1. Install HAProxy on Machine 2.
  1. Open /etc/haproxy/haproxy.cfg for editing.
  1. Add routing configuration as below:

  1. On Machine 1, add routing configuration as below to map it with the newly added microservice on Machine 2:

This ensures request is forwarded in a round robin pattern. The first request to

GET http://<machine1>:9000/tasks/get will get forwarded to http://<machine1>:8081/tasks/get.

The second request to GET http://<machine1>:9000/tasks/get will get forwarded to http://<machine2>:9000/tasks/get and so on.

Load balancing using HAProxy
A pictorial view of load balancing using HAProxy

Advantages of Using HAProxy