How to do it...

Let us implement client-side load balancing by following these steps:

  1. First, create a Maven project ch10-eureka-client that contains pom.xml with SpringCloudFinchley dependencies. Just add the core starter POM such as webflux, the actuator and the following SpringCloudNetflixRibbon module dependencies:
<dependency> 
   <groupId>org.springframework.cloud</groupId> 
   <artifactId>spring-cloud-starter-eureka</artifactId> 
</dependency> 
<dependency>   
   <groupId>org.springframework.cloud</groupId> 
   <artifactId>spring-cloud-starter-ribbon</artifactId> 
</dependency> 
  1. Then, create a typical bootstrap class suited for a Eureka client that fetches the registry and automatically registers itself to the Eureka server:
@SpringBootApplication 
@EnableDiscoveryClient 
public class HRSEurekaClientBootApplication { 
   
   public static void main(String[] args) { 
      SpringApplication.run(HRSEurekaClientBootApplication.class, 
args); 
   } 
} 
  1. In its src/main/resources, create the necessary application.properties for this Eureka client instance:
spring.application.name=hrs-client 
eureka.client.service-url.defaultZone= 
          http://localhost:5566/eureka/ 
server.port=8076 
# same as the previous recipe 
  1. Create a webflux Configuration inside org.packt.microservice.client.config with the injected RestTemplate and AsyncRestTemplate. To apply Spring Cloud Netflix Ribbon algorithm for client-side load balancing, add @LoadBalanced annotation to each injected @Bean:
@Configuration 
@EnableWebFlux 
public class WebFluxConfig { 
   
  @Bean 
   @LoadBalanced 
   public RestTemplate restTemplate() { 
        return new RestTemplate(); 
    } 
   
  @Bean 
   @LoadBalanced 
  public AsyncRestTemplate asyncRestTemplate(){ 
    AsyncRestTemplate art = new AsyncRestTemplate(); 
    return art; 
  } 
} 
  1. Copy all the needed entity models from the three microservice projects to the package org.packt.microsrevice.client.model.data for JSON encoding/decoding.
  1. Now, create the client controller that will consume any endpoints from these three microservices registered in the Eureka server. This time the service URL (for example, IP address, port, and so on) does not need to be known, since Ribbon will assist with finding the viable and healthy instances through their declared Eureka service names EMPS-SERVICE-INSTANCE, DEPTS-SERVICE-INSTANCE, and LOGIN-SERVICE-INSTANCE:
@Controller 
public class AccessRestController { 
   
  private String instanceEmp = "http://EMPS-SERVICE-INSTANCE"; 
  private String instanceDept = "http://DEPTS-SERVICE-INSTANCE"; 
     
  @Autowired 
  protected RestTemplate restTemplate; 
   
  @Autowired 
  private AsyncRestTemplate asyncRestTemplate; 
     
  @GetMapping(value="/accessListEmps", 
produces= MediaType.APPLICATION_JSON_VALUE) 
  @ResponseBody 
  public List<Employee> blockListEmp() { 
      HttpHeaders headers = new HttpHeaders(); 
     headers.set("Accept", MediaType.APPLICATION_JSON_VALUE); 
     HttpEntity<String> entity = new HttpEntity<>(headers); 
     ResponseEntity<List> response = RestTemplate 
.exchange(instanceEmp + "/listEmp", 
        HttpMethod.GET, entity, List.class); 
     return response.getBody(); 
  } 
   
  @GetMapping(value="/accessListDepts", 
produces= MediaType.APPLICATION_JSON_VALUE) 
  @ResponseBody 
  public List<Employee> blockListDepts() { 
    HttpHeaders headers = new HttpHeaders(); 
    headers.set("Accept", MediaType.APPLICATION_JSON_VALUE); 
    HttpEntity<String> entity = new HttpEntity<>(headers); 
    ResponseEntity<List> response = restTemplate 
.exchange(instanceDept + "/listDept", 
HttpMethod.GET, entity, List.class); 
    return response.getBody(); 
  } 
     
  @RequestMapping(value="/asyncSelectEmp/{id}", 
      produces=MediaType.APPLICATION_JSON_VALUE) 
  @ResponseBody 
  public Employee asyncSelectEmps( 
@PathVariable("id") Integer id){ 
    String url = instanceEmp + "/callSelectEmp/{id}.json"; 
    HttpMethod method = HttpMethod.GET; 
    HttpHeaders headers = new HttpHeaders(); 
     headers.set("Accept", MediaType.APPLICATION_JSON_VALUE); 
    HttpEntity<String> requestEntity = 
new HttpEntity<String>("params", headers); 
    ListenableFuture<ResponseEntity<Employee>> 
       future = asyncRestTemplate 
.exchange(url, method, requestEntity, 
    Employee.class, id); 
    try { 
      ResponseEntity<Employee> entity = future.get(); 
      return entity.getBody(); 
    } catch (InterruptedException e) { 
      e.printStackTrace(); 
    } catch (ExecutionException e) { 
      e.printStackTrace(); 
    }   
    return null; 
} 
} 
  1. In the case of consuming reactive REST services, directly inject the LoadBalancerClient into AccessRestController to explicitly search the service instance name from any of the healthiest instance of the registry that can provide the service URL of the desired reactive endpoint such as /selectReactEmps:
@Autowired 
private LoadBalancerClient loadBalancer; 
 
@RequestMapping("/accessReactClients") 
public Flux<Employee> sayFlux() { 
    ServiceInstance serviceInstance= 
loadBalancer.choose("EMPS-SERVICE-INSTANCE"); 
    String baseUrl=serviceInstance.getUri().toString(); 
    return WebClient.create().method(HttpMethod.GET) 
        .uri(baseUrl + "/selectReactEmps").contentType( 
MediaType.APPLICATION_JSON_UTF8).retrieve() 
.bodyToFlux(Employee.class); 
}
The Ribbon API that executes the client-side load balancing algorithm is org.springframework.cloud.client.loadbalancer.LoadBalancerClient. The annotation @LoadBalanced configures RestTemplate and AsyncRestTemplate to become a LoadBalancerClient type. The problem arises only when @LoadBalanced annotation is directly applied to the new reactive WebClient because it generates an exception:
o.s.web.reactive.function.client - java.net.UnknownHostException: EMPS-SERVICE-INSTANCE
  1. Save all files. Run Maven commands clean spring-boot:run -U and refresh the Eureka server page. If the HRS-CLIENT instance has been registered, run the entire client endpoints indicated in AccessRestController.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.227.82