Close

Spring Cloud - Load Balancing And Running Multiple Instances of a Microservice

[Last Updated: Jul 6, 2019]

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.yml

server:
  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.properties

eureka.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.properties

spring.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.properties

server.port=9080
eureka.client.serviceUrl.defaultZone=http://localhost:7777/eureka/

src/main/resources/bootstrap.properties

spring.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 Project

Dependencies 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

Load Balancing And Running Multiple Microservice Instances Select All Download
  • spring-cloud-multiple-service-instances
    • hello-eureka-server
      • pom.xml
      • hello-service
      • hello-web-client-service

    See Also