Spring Cloud: Discovering services 

Microservice architecture involves breaking down an application into smaller, independent applications that are developed and deployed separately. These individual microservices work together to deliver the overall functionality of the larger application. This brings many advantages in contrast to monolith application.

  • Microservices are relatively easy to comprehend
  • Microservices are easier to test
  • Each microservice can be scaled independently of others
  • Microservices are less prone to encountering issues with library incompatibilities.
  • Different technology choices can be made for each microservice.
  • Microservices can be deployed to production more frequently.

However, the distributed nature of microservice architecture presents its own set of difficulties, for example, microservices must contend with the challenge of inter-service communication and ensuring each service is aware of its coordinating counterparts. In fact, hardcoding microservices with specific host and port information for all other associated microservices is not only tedious but makes microservices tightly coupled. To address this issue, we need to create a microservice as service registry with the sole task of providing all the necessary information to access other microservices, simply by providing the microservice name. Microservices then register with the service registry, providing a name and all the information about how to access them. Consequently, microservices only need to know the name of the associated services and the access information is retrieved from the service registry.

Fortunately, Spring Cloud offers an out-of-the-box service registry called Eureka (Developed by Netflix)

All you need to do is to create a microservice using for example Spring Initializr and add the dependency to the Eureka Server:

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>

Additionally, you need to enable the Eureka server by annotating the application’s main bootstrap class with @EnableEurekaServer

@SpringBootApplication
@EnableEurekaServer
public class ServiceRegistryApplication {
public static void main(String[] args) {
    SpringApplication.run(ServiceRegistryApplication.class, args);
  } 
} 

And that’s it! If you start the application, you’ll have a Eureka service registry running and listening on the port 8080. However, by default, microservices that register with the service registry use port 8761. In the development environment, it may be more convenient to modify the Eureka port to 8761 using this parameter:

Server.port=8761

Here’s a configuration that can be used in development environment for the Eureka server’s application.yml file:

eureka:
  instance:
    hostname: localhost
  client:
    fetch-registryfalse
    register-with-eureka
false
server
:
  port: 8761

client.register-with-eureka set to false prevent the Eureka Service to register itself as service with other Eureka Services as Eureka service is at its own a microservice. The default value is true.

client.fetch-registry set to false to prevent Eureka to fetch other Eureka instances.

After the microservice has been started, it registers itself with the Eureka service. It’s assumed that Eureka is operating on the local machine and listening on port 8761. However, the microservice is registered with the default name of „UNKNOWN.“ To rectify this, you must specify the microservice name using this parameter:

Spring.application.name

As you can see, registration is automatic. Consequently, the ports of the various microservices are no longer hard-coded and can be chosen at random. So we don’t have to specify the port in the different microservices, instead we can set the port to 0 for all microservices. Assigning a value of 0 to the port parameter causes the application to initiate on a randomly selected available port. This eliminates a lot of concerns, as there’s no need to fret over port conflicts or which service will use which port.

It’s natural to question which microservice instance will be utilized when a microservice has numerous instances. Eureka offers load balancing on the client-side to prevent an instance from becoming overwhelmed. Ribbon (from Netflix) is a client-side load balancer available once the Netflix-Eureka-Client dependency is added to the project. All you need to do at client side is to annotate the RestTemplate or the WebClient with @LoadBalanced annotation.