Part 4 – Ribbon Client in Microservices

Ribbon Client

What have we learned so far,

PART 1 – MICROSERVICES INTRODUCTION – In this tutorial, we discussed what microservices architecture is and how its different from monolithic architecture.

 PART 2 – SCENARIO TO DEVELOP – In this tutorial, we discussed the scenario to develop.

PART 3 – FEIGN CLIENT – In this tutorial, we discussed how feign client simplifies the rest client consumption.

What is Ribbon Client?

Ribbon is a client side load balancing that gives you a lot of control over the behavior of HTTP and TCP clients. Ribbon is a Inter Process Communication (remote procedure calls) library with built in software load balancers. The primary usage model involves REST calls with various serialization scheme support.

Suppose our customer-service is running on 2 different ports as 8200 and 8201, now using feign client we can only connect to one port that is hardcoded into the @FeignClient annotation as url.
In this scenario RibbonClient will help us to dynamically manage the ports in properties file and also helps to do the load balancing in the available services.

Lets try it now.

1.    Lets add a port variable in Customer class from customer-service and account-service as follows

package com.onlyfullstack.accountservice.bean;

public class Customer {
 public Customer() {
  super();
 }

 private Long id;
 private String name;
 private String address;
 private int port;
 
 public Customer(Long id, String name, String address) {
  super();
  this.id = id;
  this.name = name;
  this.address = address;
 }

 public Long getId() {
  return id;
 }

 public void setId(Long id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public String getAddress() {
  return address;
 }

 public void setAddress(String address) {
  this.address = address;
 }

 public int getPort() {
  return port;
 }

 public void setPort(int port) {
  this.port = port;
 }
 
 
}

2. Modify controller to get the current port from which we are getting the response.

package com.onlyfullstack.customerservice.controller;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import com.onlyfullstack.customerservice.bean.Customer;

@RestController
public class CustomerController {
 
 @Autowired
 private Environment environment; //Part 3
 
 private List<Customer> listOfCustomers = new ArrayList<>(5);
 
 public CustomerController(){
   Customer customer1 = new Customer(new Long(1), "Saurabh Oza", "Pune");
   Customer customer2 = new Customer(new Long(2), "Amit Sharma", "Delhi");
   Customer customer3 = new Customer(new Long(3), "Vivek Sinha", "Mumbai");
   this.listOfCustomers.add(customer1);
   this.listOfCustomers.add(customer2);
   this.listOfCustomers.add(customer3);
 }
 
 @GetMapping("/customers")
 public List<Customer> getAllCustomers(){
  return this.listOfCustomers;
 }
 
 @GetMapping("/customers/{customer_id}")
 public Customer getCustomerDetails(@PathVariable Long customer_id) {
  Customer customer = this.listOfCustomers.stream().filter(cust -> cust.getId().equals(customer_id)).findAny().orElse(null);
  customer.setPort(Integer.parseInt(environment.getProperty("server.port"))); // Part 3
  return customer;
 }

}

3. When we run the customer-service it will run on 8200 port by default. Now we have to run the same service on 8201 port. In order to do this, we will open the Run -> Run Configuration and specify the name of Run Config as : “CustomerServiceApplication 8201” and now go to Arguments tab and add below line in VM arguments. -Dserver.port=8201.
Part 31 - Capture

4. Open CustomerServiceProxy and modify as below
Add @RibbonClient(name=”customer-service”)
Remove url from @FeignClient()

package com.onlyfullstack.accountservice.service;

import java.util.List;

import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;

import com.onlyfullstack.accountservice.bean.Customer;

// @FeignClient(url="localhost:8081" , name="customer-service")
@FeignClient(name="customer-service") //Part 3
@RibbonClient(name="customer-service") //Part 3
public interface CustomerServiceProxy {

 @GetMapping("/customers")
 public List<Customer> getAllCustomers();
 
 @GetMapping("/customers/{customer_id}")
 public Customer getCustomerDetails(@PathVariable("customer_id") Long customer_id);
}

5. How the ribbon client will identify the available customer-services ? for this we need to add below entry in application.properties file as
customer-service.ribbon.listOfServers=http://localhost:8200,http://localhost:8201

6. Run the accounts service to check if its working.
Lets hit the accounts-service as http://localhost:8100/accounts/1

7. Lets again hit the url : http://localhost:8100/accounts/1 ,
In both the cases we are getting different ports as ribbon is doing the load balancing and sending the request to each ports.
Part 32 - Capture

Part 33 - Capture

Source Code
Download source code of microservice with spring cloud from below git repository :

Lets go to our next tutorial where we will discuss

Part 5 – Eureka Naming Server

In this tutorial we will understand below topics
– What is Eureka Naming Server?
– Advantages of eureka naming server
– How to implement eureka naming server in microservices?
PART 5 – MICROSERVICES WITH SPRING CLOUD : EUREKA NAMING SERVER

Microservices Tutorial

Microservices Tutorial

Related Posts

Microservices Interview Questions