Introduction to Spring Cloud Rest Client with Netflix Ribbon

1. Introduction

Netflix Ribbon is an Inter Process Communication (IPC) cloud library. Ribbon primarily provides client-side load balancing algorithms.

Apart from the client-side load balancing algorithms, Ribbon provides also other features:

  • Service Discovery Integration – Ribbon load balancers provide service discovery in dynamic environments like a cloud. Integration with Eureka and Netflix service discovery component is included in the ribbon library
  • Fault Tolerance – the Ribbon API can dynamically determine whether the servers are up and running in a live environment and can detect those servers that are down
  • Configurable load-balancing rules – Ribbon supports RoundRobinRuleAvailabilityFilteringRuleWeightedResponseTimeRule out of the box and also supports defining custom rules

Ribbon API works based on the concept called “Named Client”. While configuring Ribbon in our application configuration file we provide a name for the list of servers included for the load balancing.

Let’s take it for a spin.

2. Dependency Management

The Netflix Ribbon API can be added to our project by adding the below dependency to our pom.xml:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>

The latest libraries can be found here.

3. Example Application

In order to see the working of Ribbon API, we build a sample microservice application with Spring RestTemplate and we enhance it with Netflix Ribbon API along with Spring Cloud Netflix API.

We’ll use one of Ribbon’s load-balancing strategies, WeightedResponseTimeRule, to enable the client side load balancing between 2 servers, which are defined under a named client in the configuration file, in our application.

4. Ribbon Configuration

Ribbon API enables us to configure the following components of the load balancer:

  • Rule – Logic component which specifies the load balancing rule we are using in our application
  • Ping – A Component which specifies the mechanism we use to determine the server’s availability in real-time
  • ServerList – can be dynamic or static. In our case, we are using a static list of servers and hence we are defining them in the application configuration file directly

Let write a simple configuration for the library:

public class RibbonConfiguration {

    @Autowired
    IClientConfig ribbonClientConfig;

    @Bean
    public IPing ribbonPing(IClientConfig config) {
        return new PingUrl();
    }

    @Bean
    public IRule ribbonRule(IClientConfig config) {
        return new WeightedResponseTimeRule();
    }
}

Notice how we used the WeightedResponseTimeRule rule to determine the server and PingUrl mechanism to determine the server’s availability in real-time.

According to this rule, each server is given a weight according to its average response time, lesser the response time gives lesser the weight. This rule randomly selects a server where the possibility is determined by server’s weight.

And the PingUrl will ping every URL to determine the server’s availability.

5. application.yml

Below is the application.yml configuration file we created for this sample application:

spring:
  application:
    name: spring-cloud-ribbon

server:
  port: 8888

ping-server:
  ribbon:
    eureka:
      enabled: false
    listOfServers: localhost:9092,localhost:9999
    ServerListRefreshInterval: 15000

In the above file, we specified:

  • Application name
  • Port number of the application
  • Named client for the list of servers: “ping-server”
  • Disabled Eureka service discovery component, by setting eureka: enabled to false
  • Defined the list of servers available for load balancing, in this case, 2 servers
  • Configured the server refresh rate with ServerListRefreshInterval

6. RibbonClient

Let’s now set up the main application component snippet – where we use the RibbonClient to enable the load balancing instead of the plain RestTemplate:

@SpringBootApplication
@RestController
@RibbonClient(
  name = "ping-a-server",
  configuration = RibbonConfiguration.class)
public class ServerLocationApp {

    @LoadBalanced
    @Bean
    RestTemplate getRestTemplate() {
        return new RestTemplate();
    }

    @Autowired
    RestTemplate restTemplate;

    @RequestMapping("/server-location")
    public String serverLocation() {
        return this.restTemplate.getForObject(
          "http://ping-server/locaus", String.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(ServerLocationApp.class, args);
    }
}

We defined a controller class with the annotation @RestController; we also annotated the class with @RibbonClient with a name and a configuration class.

The configuration class we defined here is the same class that we defined before in which we provided the desired Ribbon API configuration for this application.

Notice we also annotated the RestTemplate with @LoadBalanced which suggests that we want this to be load balanced and in this case with Ribbon.

7. Failure Resiliency in Ribbon

As we discussed earlier in this article, Ribbon API not only provides client side load balancing algorithms but also it has built in failure resiliency.

As stated before, Ribbon API can determine the server’s availability through the constant pinging of servers at regular intervals and has a capability of skipping the servers which are not live.

In addition to that, it also implements Circuit Breaker pattern to filter out the servers based on specified criteria.

The Circuit Breaker pattern minimizes the impact of a server failure on performance by swiftly rejecting a request to that server that is failing without waiting for a time-out. We can disable this Circuit Breaker feature by setting the property niws.loadbalancer.availabilityFilteringRule.filterCircuitTripped to false.

When all servers are down, thus no server is available to serve the request, the pingUrl() will fail and we receive an exception java.lang.IllegalStateException with a message “No instances are available to serve the request”.

8. Conclusion

In this article, we discussed Netflix Ribbon API and its implementation in a simple sample application.

The complete source code for the example described above can be found on the GitHub repository.

Related posts:

Stack Memory and Heap Space in Java
Guide to the Synchronized Keyword in Java
Batch Processing with Spring Cloud Data Flow
How to Read HTTP Headers in Spring REST Controllers
Abstract class và Interface trong Java
Lập trình đa luồng trong Java (Java Multi-threading)
Java Program to Compute Discrete Fourier Transform Using the Fast Fourier Transform Approach
Guide to UUID in Java
Dynamic Proxies in Java
Java Program to Implement Queue using Linked List
Java Byte Array to InputStream
Giới thiệu Swagger – Công cụ document cho RESTfull APIs
Java Program to Generate a Random UnDirected Graph for a Given Number of Edges
Java Program to Evaluate an Expression using Stacks
Java Program to Implement Double Order Traversal of a Binary Tree
Lớp LinkedHashMap trong Java
Assert an Exception is Thrown in JUnit 4 and 5
Call Methods at Runtime Using Java Reflection
Merging Streams in Java
Prevent Brute Force Authentication Attempts with Spring Security
Các kiểu dữ liệu trong java
The StackOverflowError in Java
Calling Stored Procedures from Spring Data JPA Repositories
Java Program to Solve Knapsack Problem Using Dynamic Programming
Java Program to Implement PriorityBlockingQueue API
Write/Read cookies using HTTP and Read a file from the internet
Java Program to Implement Patricia Trie
Java Program to Perform Polygon Containment Test
How to Count Duplicate Elements in Arraylist
Hướng dẫn Java Design Pattern – Memento
Spring Security Login Page with React
Removing all Nulls from a List in Java