How to talk to services in a service registry in Spring Boot?

In this post we saw how to set up a service registry in Spring Boot.

You can register all your microservices in a single service registry which will make it easier for each microservice to communicate with each other.

In this post let’s see how to do the communication part.

How can a microservice discover another microservice and communicate with it?

In traditional architecture , they communicate with each other through HTTP.

You provide the HTTP URL and make a HTTP call.

For this you need to know the domain and the port where the service resides on.

Using service registry you still make the HTTP call of course but just use the service name.

Here is an example of how to do it:

Let’s consider the same set of microservices used in this post .

I started the server “eureka-server” and spun up two more microservices (eureka clients ) “eureka-client” and “eureka-client-2”:

You may get the below error message on the above screen when you start up the eureka server:

EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY’RE NOT. RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE

You get this because Eureka server expects the eureka clients to send a heart beat to it (simple REST call for health check up) every now and then. You need to configure how often this should happen on the server.

Simply adding the below property on the server’s application.yml will remove this error :

eureka:
  server:
    renewal-percent-threshold: 0.85

0.85 is the default standard value (1 heart beat call every 0.85 minute).

Now let’s create a simple REST API on eureka-client-2 microservice:

package com.example.eureka.client;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {

	
	
	@GetMapping("client2")
	public String client2() {
		
		return "I am a REST API in client 2";
	}
}

Advertisements

We are going to call the above REST API from “eureka-client” microservice through service registry.

Let’s create a REST API in “eureka-client” which will in turn call the above REST API:

package com.example.eureka.client;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;


@RestController

public class TestController {

	@Autowired
	private DiscoveryClient discoveryClient;
	
	@GetMapping("/test")
	public String test() {
		
		
		List<ServiceInstance> instances = 	discoveryClient.getInstances("eureka-client-2");
		
		ServiceInstance instance =  instances.get(0);
		
		System.out.println(instance);
		
		String url = instances.get(0).getUri()+"/client2";
		
		System.out.println(url);
		
		RestTemplate restTemplate = new RestTemplate();
		
		String response = restTemplate.getForObject(url, String.class);
		
		return response;
		
	}
}

As you see in the above code , you retrieve an instance of the microservice “eureka-client-2” using the class DiscoveryClient . This class should be imported from “org.springframework.cloud.client.discovery” package and not from the one provided by netflix.

Once you retrieve the instance you get the service HTTP URL from it.

You then append the endpoint you want to call (“/client2” in this case)

And then make a regular REST API call ( I have used RestTemplate here)

Let me test the above code:

Client 1(eureka-client) made a call to Client 2 (eureka-client-2) and returned the response as shown above.

Shortcomings:

There is one shortcoming in using DiscoveryClient to fetch a service instance.

If there are multiple instances of the same service running you need to choose one among them.

In the above example I am just choosing the first one.

What if there are two instances running and you need to distribute requests?

That is where the next part in Service Registry design pattern comes in.

Load Balancing.

You can do either client side load balancing or server side load balancing.

Check this post to know how to do client side load balancing using Spring Cloud Load Balancer:

Advertisements

And this one to know how to server side load balancing using Spring Cloud Gateway:

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s