Client-Side Load Balancing Example

About

Client-side load balancing is a method where the load-balancing logic is executed on the client rather than a centralized load balancer.

Netflix Ribbon

Netflix Ribbon is one of the popular libraries for implementing client-side load balancing in Java applications, often used in microservice architectures, particularly in conjunction with Spring Cloud.

What is Ribbon?

Ribbon is a client-side load balancer that automatically distributes traffic across multiple service instances based on a configurable algorithm. Unlike traditional load balancers (such as HAProxy or NGINX), which reside between clients and servers, Ribbon allows clients to perform load balancing themselves by maintaining a list of server instances.

How Ribbon Works?

Ribbon works by:

  1. Maintaining a list of available service instances: Ribbon is responsible for keeping track of all the instances of a service, typically using service discovery mechanisms like Eureka or statically configured lists.

  2. Load Balancing Requests: Each time a client makes a request, Ribbon selects an instance of the service based on a load-balancing strategy (e.g., round-robin, random, or weighted).

  3. Routing Requests to Instances: Once Ribbon has selected a service instance, the client sends the request directly to that instance.

Key Components of Ribbon

  1. ServerList: Ribbon uses this to maintain a list of available servers (service instances). This can be dynamically populated using service discovery tools like Eureka, or it can be hardcoded.

  2. ILoadBalancer: This interface defines the load balancer, which determines how to pick a server from the list of available instances. Ribbon provides default implementations, such as round-robin or random.

  3. Ping: Ribbon can periodically check if instances are up or down by "pinging" them to ensure the health of the services. This ensures that requests are not sent to unhealthy instances.

  4. ServerListFilter: This filters the available server list to exclude servers based on certain conditions (e.g., health status, region).

  5. IRule: This defines the load-balancing strategy (or rule) that Ribbon uses to select a server. Some built-in strategies include:

    • RoundRobinRule: Distributes requests evenly across all available instances.

    • RandomRule: Chooses a random instance for each request.

    • WeightedResponseTimeRule: Chooses instances based on their response time, giving preference to faster instances.

Example with Static Server List

Create a client service maven project say sample-project-ribbon .

Add the following dependencies

In this example, parent pom version used as 2.7.11

Create RestTemplateConfig.java configuration class with below content

Create RibbonConfig.java configuration class with below content

Create ClientController.java controller class having API call with load balanced ribbon host

Create a main application class

Create application.yaml properties file

Sample Dockerfile to create image for the above service

Now, build the service and create docker image

Verify the generated docker image

Now, lets create a sample service maven project say sample-project with an endpoint being called by above client API.

Add the following dependencies in pom.xml file

We may need to add spring-boot-maven-plugin to be able to generate jar file.

Create a sample controller class with 1 endpoint

We may notice the use of SERVER_INSTANCE variable. We will be setting it the docker compose file as a environment variable since we will need to create multiple instance (more than 1) of this service to test the load balancing feature.

Create a main application file

application.yaml file

Build the project to generate jar file (to be used later in docker compose file)

We will use the generated jar file directly in docker-compose instead of creating docker image for above service

Now, we have both the services ready. Let's create docker-compose.yml file

We can keep this docker-compose file in root of sample-project since we need to provide relative path of jar file

Run the docker compose file

Now, hit the API http://localhost:8080/call-backend multiple times. We will notice the change of Server Instance value in the API response meaning the response was provided by the respective service instance.

Last updated