Spring Boot Service Discovery with Netflix Eureka

Microservices are dynamic. There can be multiple instances of a microservice running at a time. The number of instances can increase or decrease according to the requirement. The spring boot framework provides service discovery support with the Netflix Eureka library.

A service registry gives an easy way to register many microservice instances. Also, a service client can look up the service registry and discover the required service.

Table of Contents

Two main benefits of service discovery are:

  • It separates service clients from actual service with physical address by introducing an intermediary layer between them.
  • It provides an easy way to horizontally scale up/down service instances and also removes failing services from the service lookup registry.

While scaling up/down, there is no impact on service consumers as there will be a service registry layer, which separates service consumers from actual service instances.

Using service discovery makes service highly available. Using a single instance of the eureka server is not a good idea. We also should have multiple instances of eureka service to avoid a single point of failure.

Setting up Spring Eureka Server

Create a new spring boot project and also add the spring-cloud-starter-netflix-eureka-server dependency.

With STS, we have to choose the eureka server option while creating the project as shown below.

eureka-server-spring-io

Finally, after adding all the required dependencies, the pom.xml file looks as given below.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.asb.example</groupId>
    <artifactId>spring-boot-eureka-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-eureka-server</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
        <maven-jar-plugin.version>3.1.1</maven-jar-plugin.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>
    </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>

Now we have to enable the eureka server using the annotation the @EnableEurekaServer. We have to add this annotation to our spring boot application class.

This will also auto-configure a number of different configurations that are required for the constructing eureka server.

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

Add the below properties to application.properties.

server.port= 8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
  • server.port: Defines the eureka server port. 8761 is a commonly used port for the eureka server.
  • eureka.client.register-with-eureka: A service registers itself as a eureka client if the value of this property is to true. Our eureka server is not a eureka client, so we have to set this property to false.
  • eureka.client.fetch-registry: If true, client service fetches the available service registry information and also maintains a local copy. Our eureka server does not require this property to be enabled.

Run the spring boot application.

Access the application on http://localhost:8761 on any browser. We will get the eureka console, as shown below.

Eureka server console

Also, this eureka console contains information about server uptime, currently registered service instances, environment details, memory details, etc.

Avoiding single point of failure

If we use one eureka server instance, we are building a single point of failure for our application. To avoid this, we can also run multiple instances of the eureka server.

To run multiple instances of the eureka server on a local windows machine, we have to update our systems host entry. We can find the host file on the Windows system under C:/Windows/System32/drivers/etc directory.

Add the following entries to the host file.

127.0.0.1       peer1
127.0.0.1       peer2

Let us create two instances of the eureka server with hostname peer1 and peer2. For this, we have to create two different configuration property files “application-peer1.properties” and “application-peer2.properties“. Here, peer1 and peer2 are two different spring profiles.

application-peer1.properties:

server.port= 8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.instance.hostname=peer1
eureka.client.serviceUrl.defaultZone=http://peer2:8762/eureka

application-peer2.properties:

server.port= 8762
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
eureka.instance.hostname=peer2
eureka.client.serviceUrl.defaultZone=http://peer1:8761/eureka
  • eureka.instance.hostname: Defines the host name.
  • eureka.client.serviceUrl.defaultZone: This property points to the other server instance.

Run the application with different profiles with the required run configuration.

With STS we can also achieve this by Right click on Project > Run As > Run configuration.

Under the Arguments tab, we can set the active spring profile with peer1 and peer2 as shown below.

Run the eureka server application with a different active profile.

run configuration eureka server

Test the eureka server replicas, by accessing http://localhost:8761. We should be able to get the eureka server dashboard, with replica server information as shown below.

The highlighted section tells the available discovery service replicas. In our example, we can recognize the peer2 replica.

Eureka server DS replica

We can also access the peer2 replica by accessing http://localhost:8762/. We should be able to see the peer1 discovery service replica, as shown below.

Eureka server DS replica peer 2

Also, we can see registered replica under the “General Info” tab, as shown below.

Eureka registered replicas - general info tab

Registering services with eureka

Till now, we have created a eureka server. We also learned how to create multiple instances of the eureka server. Now let us create a eureka client and register it into the eureka server registry.

Create a new spring boot application with the spring-cloud-starter-netflix-eureka-client and the spring-boot-starter-web dependency.

With STS IDE, we can choose the dependencies easily, as shown below.

Eureka client example

Finally, after adding all the required dependencies, the pom.xml file may look like below.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.asb.example</groupId>
    <artifactId>spring-boot-eureka-client</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot-eureka-client</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR2</spring-cloud.version>
        <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </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>

We have to enable the eureka client to get registered with the eureka server registry by adding the @EnableEurekaClient annotation.

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

Add the below property on the application.properties configuration file.

spring.application.name=my-client

Start the eureka client application.

The client application gets started and registers itself on the eureka service discovery registry.

We can access the Eureka server dashboard to check if the service is registered, as shown below.

Eureka client registered for discovery

We can also use http://localhost:8761/eureka/apps/{app-id} to get the service registry information.

spring boot netflix eureka

Finally, we have successfully registered service into the Eureka service registry server.

Conclusion

In this article, we learned how to create a eureka server.

We also learned how to create a discovery service replica by using different hostnames.
Finally, we created a client service and registered it into the eureka server.

Example code is available on Github.

Spring Boot Service Discovery with Netflix Eureka
Scroll to top

Discover more from ASB Notebook

Subscribe now to keep reading and get access to the full archive.

Continue reading