In the last example we saw how to use @RestTemplate as client side load balancer. In this tutorial we will run multiple instances of a service and access them via @RestTemplate load balancer.
In Spring cloud, a service instance is registered with an ID that is equal to the following:
${spring.cloud.client.hostname}:${spring.application.name}:${spring.application.instance_id:${server.port}}}
In a typical microservice application multiple instances of a service should run on different machines to achieve load balancing. If we want to run multiple instance on a single development machine then we cannot run them with above default because of the same port.
We can override this default as follows which generates random ID and port:
server.port=${PORT:0}
${spring.application.name}:${vcap.application.instance_id:${spring.application.instance_id:${random.value}}}
Example
Eureka Server Instance
src/main/resources/application.ymlserver:
port: 7777
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
@SpringBootApplication
@EnableEurekaServer
public class HelloEurekaServerMain {
public static void main(String[] args) {
SpringApplication.run(HelloEurekaServerMain.class, args);
}
}
Run above main class from IDE.
Creating hello microservice and running multiple instances
src/main/resources/application.propertieseureka.client.serviceUrl.defaultZone=http://localhost:7777/eureka/
server.port=${PORT:0}
eureka.instance.instance-id=${spring.application.name}:${spring.application.instance_id:${random.value}}
src/main/resources/bootstrap.propertiesspring.application.name=hello-service
@RestController
public class HelloController {
@Value("${eureka.instance.instance-id}")
private String instanceId;
@GetMapping("/hello")
public HelloObject getHelloWordObject() {
HelloObject hello = new HelloObject();
hello.setMessage("Hi there! instance id: " + instanceId);
return hello;
}
}
@SpringBootApplication
@EnableDiscoveryClient
public class HelloServiceMain{
public static void main(String[] args) {
SpringApplication.run(HelloServiceMain.class, args);
}
}
Run above main class multiple times from your IDE.
Creating hello web client
src/main/resources/application.propertiesserver.port=9080
eureka.client.serviceUrl.defaultZone=http://localhost:7777/eureka/
src/main/resources/bootstrap.propertiesspring.application.name=hello-web-client-service
@SpringBootApplication
@EnableDiscoveryClient
public class HelloWebClientServiceMain {
@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(HelloWebClientServiceMain.class, args);
}
}
@Controller
public class HelloWebClientController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/")
public String handleRequest(Model model) {
//accessing hello-service
HelloObject helloObject = restTemplate.getForObject("http://hello-service/hello", HelloObject.class);
model.addAttribute("msg", helloObject.getMessage());
model.addAttribute("time", LocalDateTime.now());
return "hello-page";
}
}
Run above main class.
Accessing Eureka at http://localhost:7777/
Accessing web client service at http://localhost:9080/
Refreshing again will give us the other instance confirming our load balancer (RestTemplate) is working as expected.
Example ProjectDependencies and Technologies Used: - Spring Boot 2.0.4.RELEASE
Corresponding Spring Version 5.0.8.RELEASE - Spring Cloud Finchley.SR1
- spring-cloud-starter-netflix-eureka-server 2.0.1.RELEASE: Spring Cloud Starter Netflix Eureka Server.
- spring-boot-starter-web : Starter for building web, including RESTful, applications using Spring
MVC. Uses Tomcat as the default embedded container.
- spring-cloud-starter-netflix-eureka-client 2.0.1.RELEASE: Spring Cloud Starter Netflix Eureka Client.
- spring-boot-starter-thymeleaf : Starter for building MVC web applications using Thymeleaf views.
Uses org.thymeleaf:thymeleaf-spring5 version 3.0.9.RELEASE - JDK 1.8
- Maven 3.5.4
|