Open In App

Implementation of Spring Cloud Netflix – Eureka

In this article, we will learn about server-side and client-side service discovery in Spring Cloud Netflix Eureka. By using the central registry service, we can discover all of the microservices that are catering to our web application along with the respective port numbers they have occupied on startup. This central registry service is what is termed as Spring Cloud Netflix Eureka Server. This Eureka server fulfills the sole purpose of service discovery. Each of the microservices that register themselves with the Eureka server sends their respective status updates at regular intervals of time to the Eureka server.

In this way, the Eureka server is continuously updated about the status of each service (whether the service is up and running). It also keeps track of the number of requests being handled by each instance of those respective services, which plays an important role in the load-balancing aspect of microservices.



Next Step in Microservices

After following the microservices style of software development, there arises the need for certain additional components to be developed. As we have seen how single web application was broken down into smaller pieces (services). With new requirements that may come up in the future, the number of services catering to our web application would increase. With increasing microservices being developed as per this model of software development, there came the need for a central location to track these services.

In this way, it would be easier to identify which of the services are currently up and running and which of the services have failed to start on the application run time.



Prerequisites to the Topic:

In our example, we shall set up a Eureka Server along with 2 sample services that would register themselves with the Eureka Server for the purpose of the service discovery mechanism. The 2 sample services would be a Cart Service and a User Service. The user places the request for a specific item_id by invoking the User Service’s endpoint and then it calls the Cart Service which will place a request for that item_id in the inventory.

To create these services, we shall use the Spring Starter Project utility, provided by the Eclipse IDE.

Creating the Eureka Server

Create the Eureka Server Spring Boot Project in Eclipse IDE by going to,
File -> New -> Spring Starter Project

This will open the Spring Starter Project dialogue box below. Enter the project metadata details, giving any name to your project that you choose and click on Next.

Choose the dependency below to be added to your project and click on Next:

Click on Next and then finish, this will generate the Eureka Server project.

Creating the User Service

In the Eclipse IDE, go to File -> New -> Spring Starter Project . This will open the Spring Starter Project dialogue box below.

Enter the project metadata details, giving any name to your project that you choose and click on Next.

Choose the dependencies below to be added to your project and click on Next:

Click on Next and then finish, this will generate the User Service project.

Creating the Cart Service Project

In the Eclipse IDE, go to File -> New -> Spring Starter Project . This will open the Spring Starter Project dialogue box below.

Enter the project metadata details, giving any name to your project that you choose and click on Next.

Choose the dependencies below to be added to your project and click on Next:

Click on Next and then finish, this will generate the Cart Service project.

Starting with developing the code base for the User Service




import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
  
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class UserServiceApplication
{
  
    public static void main(String[] args) 
    {
        SpringApplication.run(UserServiceApplication.class, args);
    }
  
}

In the above code snippet:

Creating the Controller class




import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
  
import com.elkstack.feign.Feign;
  
  
@RestController
public class UserController 
{
    @Autowired
    Feign feign;
  
  
    @GetMapping("/add/{item_id}")
      public String addUsersItem(@PathVariable("item_id") String item_id)
      {
  
        feign.addToCart(item_id);
          
         return "Item with id: " + item_id  + " selected to add in cart" ;
       
      }
  
}

In the above code snippet:

Creating the Feign Interface




import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
  
@FeignClient(name="CartService")
public interface Feign
{
    @GetMapping("/addToCart/{item_id}")
    public String addToCart(@PathVariable("item_id") String item_id);
      
}

In the above code snippet:

The application.properties file:

spring.application.name=UserService
server.port=8090
eureka.instance.preferIpAddress = true
eureka.client.registerWithEureka = true
eureka.client.fetchRegistry = true
eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka

In the above properties file:

The pom.xml file for the User Service




<?xml version="1.0" encoding="UTF-8"?>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.16</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>elkstackmumbai</groupId>
    <artifactId>UserService</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>UserService</name>
    <description>User Service MicroService</description>
    <properties>
        <java.version>17</java.version>
        <spring-cloud.version>2021.0.8</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
  
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
  
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  
</project>

The main Maven dependencies to be added are:

Now, Creating the Cart Service




import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
  
@SpringBootApplication
@EnableEurekaClient
public class CartServiceApplication {
  
    public static void main(String[] args) {
        SpringApplication.run(CartServiceApplication.class, args);
    }
  
}

In the above code snippet:

Creating the Controller Class




import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
  
@RestController
public class CartServiceController 
{
  
    @GetMapping("/addToCart/{item_id}")
    public String addToCart(@PathVariable("item_id") String item_id)
    {
        return "Item with id : " + item_id+ "added to cart";
    }
}

In the above code snippet:

The application.properties file for the Cart Service:

server.port=8095
spring.application.name=CartService
eureka.instance.preferIpAddress = true
eureka.client.registerWithEureka = true
eureka.client.fetchRegistry = true
eureka.client.serviceUrl.defaultZone = http://localhost:8761/eureka

In the above properties file:

The pom.xml file for the Cart Service




<?xml version="1.0" encoding="UTF-8"?>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.16</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>elkstackmumbai</groupId>
    <artifactId>cartservice</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>CartService</name>
    <description>Cart Service App</description>
    <properties>
        <java.version>17</java.version>
        <spring-cloud.version>2021.0.8</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
  
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
  
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  
</project>

The main Maven dependencies to be added into the pom.xml file:

Now Creating the Eureka Server




import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
  
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
  
    public static void main(String[] args) {
        SpringApplication.run(EurekaApplication.class, args);
    }
  
}

In the above code snippet:

The application.properties file for the Eureka Server:

spring.application.name=Eureka
server.port=8761
eureka.instance.hostname=localhost
eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false
eureka.client.serviceUrl.defaultZone=http://${eureka.instance.hostname}:${server.port}/eureka

In the application.properties file:

The pom.xml file for the Eureka Server:




<?xml version="1.0" encoding="UTF-8"?>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.16</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>elkstackmumbai</groupId>
    <artifactId>EurekaService</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Eureka</name>
    <description>Eureka Central Registry Service</description>
    <properties>
        <java.version>17</java.version>
        <spring-cloud.version>2021.0.8</spring-cloud.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
  
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
  
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
  
</project>

The main Maven dependency to be added in the pom.xml file is:

After we have created these Spring Boot projects, we can now hit the endpoint: http://localhost:8090/add/2 through Postman:

As seen in the above image, the item_id: 2 is provided as the input to the given endpoint. The respective User Service then calls the Cart Service which adds the requested item_id: 2 in the cart.

Viewing Registered Services through the Central Registry Eureka Server

Hit the endpoint: http://localhost:8761/

This will open the Eureka server dashboard below:

Below we can see the Services registered with the Eureka Server:

As seen from the above image, the 2 services that are User Service, Cart Service that are registered with the Eureka Server are displayed along with their port numbers on which they are currently up and running. The Cart Service is running on port number: 8095. While, the User Service is running on port number: 8090.

In this way, we can accurately identify which of the services have not yet been registered with the Eureka server due to any failures that may prevent the given services from being up and running at the application start up time.

Conclusion

As we seen through the above code example, how we set up the services and got them registered with the Eureka server. Using this Eureka server, we were able to view all the services registered with it and complete our process of service discovery in the microservices environment.


Article Tags :