Microservices In Spring Boot II- Service Discovery

Nikhil Bhatnagar
Dev Genius
Published in
6 min readDec 28, 2021

--

Microservices are basically small casts of a bigger mold and explaining everything in detail is an article here. So as per the previous article, you might have noticed that the URLs of microservices are hardcoded. Now, this is an extremely bad practice because of the following:-

· Url’s might change which can lead to us changing it inside our code.

· Cloud deployed services have diff urls. Aws services have aws as prefix and so on. Hence a common pattern is difficult to find.

· Load balancing is impossible with this method.

· We can have multiple environments.

Photo by Luca Bravo on Unsplash

An alternative to hard coding is moving URL’s to applications file, i.e. use it as environment variables but the thing is that this approach is also “hardcoding” despite it saving us some typing or few lines of code. So, in order to avoid this, we have a design pattern or a way called Service discovery. As the name suggests, service discovery is basically client searching for microservices. We have a layer of server called discovery or discovery server to be precise, which takes in request from client, search for microservices and returns back the URL to client.

fig 1.0

The image above describes the process of service discovery. Breaking down the annotations in the image:-

Step x is basically the client requesting the server for service C.

Step y is service C providing its URL to the server which in turn passes it on to the client.

Step z is the result of step y where the client directly calls service C after obtaining its URL from the discovery server.

As the client is requesting service, hence the above process is also called client-side discovery. The reverse of it, i.e. service side discovery also happens in a very similar way. By default, spring provides client side discovery implementation and hence we’ll go forward with the same in this article. Now, service discovery is a very quotidian thing. Various technologies use various libraries to help and facilitate the developers regarding the same. In Spring libraries like Eureka, Ribbon, Zuul, Hysterix etc are popularly used for service discovery and other services. Eureka, built by Netflix is arguably the most used of them all and we’ll be looking into eureka for this article.

Eureka works on a client-server model. Eureka server is basically the microservice that behaves as discovery server and helps in finding other servers whereas eureka clients are those microservices that consume responses from eureka servers. In other words, everything apart from the discovery server is the client. Eg:- in figure 1.0 (above), the diamond-shaped discovery is the server whereas all others are clients.

Using Eureka involves three basic steps:-

> Setting up the Eureka server.

> Registering microservices for using the server, i.e having microservices to publish their response to discovery.

> Consuming the response from the discovery to find a server

Elaborating each step:-

Setting up the Eureka server:-

Eureka server is nothing but a spring boot project having an eureka server or spring cloud discovery dependency. So, we’ll just create a new project from spring starter and open it in any IDE. Note that we don’t need any other dependency for the eureka server to spawn up in the case of java 8. For java 9 or java 10 and above we need to add jaxb dependencies (jaxb-api, jaxb-impl, jaxb-runtime and activation) for our application to work. This is because jaxb was deprecated from java 9 and above.

Also, before starting up the application we need to add the following to our project:-

· Inside our main class i.e our config class, we need to add @EnableEurekaServer just below @SpringBootApplication. This tells spring that our project is the server.

Secondly, inside our application.properties we need to add

The above is necessary as eureka server by default is also a client. It can link up with other servers or other registry services. So to avoid that, we need to add the following. Now, starting up the application and switching up to http://localhost:8761/ will give a well-defined UI showing various details about our server.

Registering microservices for using the server

Now, we need to convert our existing microservices into eureka clients. In order to do so:-

· Firstly we need to add the client dependency in the pom of our existing microservices, i.e spring applications.

· Secondly, we need to add the spring cloud version property to our project. To do so, just add the below between <properties></properties> just below java-version. Defining the version is a necessary to practice as we can have many clouds in the future and defining it once is necessary.

<spring-cloud-version>Greenwich.RELEASE</spring-cloud-version>

· Also for better understanding, add a name to your application using spring.application.name=name_you_want Now re-run your project and refresh the eureka ui. A service with your given name will be registered on the eureka ui.

· Keep repeating the same steps with all available microservices and we’ll be good to go with our service registry.

Now a valid question may arise as to how does the client find the eureka server? Well, a reasonable explanation to the above is the port on which eureka is running currently is the default port. As such, the client checks the default port finds eureka there and registers itself. In case we change the port then we need to explicitly specify the server port number to our client.

Consuming the response from the discovery

The consuming response generally applies to the services where we hard coded the URL. So to consume the response we need to:-

· Add @LoadBalanced above the rest template or the web client instantiation we are using to call the microservices. Explaining it in better terms, if we are using rest-template to do the API call to microservice, then add the above annotation at the time of initialization of rest template. (i.e. RestTemplate t= new restTemplate, so add just above this line).

· Now, go to the hardcoded URL and replace the hardcode with the name of the client that has been registered within the eureka discovery. Eg:- initially we were doing

http://localhost:8082/movies/createUser

Now, we’ll replace this by

http://movie-demo-test/movies/

where, movie-info-service is the name of our client registered to eureka and is also analogous to localhost:8082

The annotation is called @LoadBalanced because apart for discovery, it also does load balancing. Suppose, we have 5 instances of movie-demo-test. At the time of service discovery, spring actually checks the load information on each microservice instant and gives us the best one possible. Although the default implementation is not the best, yet it does its job in the best possible manner.

Further, Spring provides DiscoveryClient, an interface that helps us to choose between various instances etc, and thus helps in custom load balancing. The discovery server monitors its client's uptime using “heartbeat” model. In case a service goes down, the load balancer will notice it and automatically manage the load coming to it.

So that’s pretty much a very simple example of service discovery and the basics of microservices in spring boot. The next step from here is probably looking into the depths of load balancing and fault tolerance.

Hope you liked the above article. If you want similar articles based on any java or node/js based technology, please feel free to share that in the comments. I’ll be happy to dig into and write something similar for the same.

Thanks for reading!.

--

--

A tech enthusiast who loves to read and write about new technologies and trends. Software engineer @HashedinByDeloitte