Spring Cloud Netflix Eureka

author-imageBy Dhiraj, 23 February,2018   1K

This tutorial is about spring cloud Netflix Eureka. Here, we will be creating eureka discovery server and microservices that will itself register to the discovery server and the client that will use netflix client API to discover the service and consume the microservices exposed by the service with sample example.Hence, we will be developing 3 different spring boot application for each discovery server, service and client.Also, we wil take a look into default eureka dashboard and different useful information available in the dashboard. Spring cloud netflix provides Netflix OSS integrations for spring boot apps using simple annotation based configuration.Now is the time when we create microservices instead of a bulk application and deploy these microservices to cloud. In this architecture, service discovery is one of the key tenets.Service discovery automates the process of multiple instance creation on demand and provides high availability of our microservices.Here we will be using Eureka as the Netflix Service Discovery Server and Client.

Spring Cloud Eureka Discovery Server

Discovery server is the registry of all the available services.The different services can register and de-register themselves on this server.Implementing eureka discovery server using spring boot is very simple. For this purpose, first we will create a spring boot app with below dependencies from start.spring.io and import it in our IDE.

spring-cloud-netflix-server

This brings following maven dependencies.The dependencies required to enable spring cloud is spring-cloud-dependencies.

pom.xml
<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>pring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-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>

And we have following properties defined in the application.properties.Here, spring.application.name provides the unique identifier of this service.while starting discovery server, it will try to register with its peer discovery server for high aviability which we dont have for this tutorial.We don't have multiple instances of discovery server.Hence eureka.client.register-with-eureka is set to false.

Similarly, we have eureka.client.fetch-registry property that indicates whether this client should fetch eureka registry information from eureka server. And the server.port is to define the port on which our dicovery server will be running.

spring.application.name=discovery-server
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
server.port=8761

Now let's define our DiscoveryServerApplication.@EnableEurekaServer will enable the eureka server configurations. When we run this class as a java program, it will add new peer node at http://localhost:8761/eureka/ and our microservice will be invoking this url to register itself.

DiscoveryServerApplication.java
package com.devglan.discoveryserver;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

@EnableEurekaServer
@SpringBootApplication
public class DiscoveryServerApplication {

	public static void main(String[] args) {
		SpringApplication.run(DiscoveryServerApplication.class, args);
	}
}

That's it for discovery server. Our discovery server is ready to accept registration request from any service at http://localhost:8761/eureka

Spring Cloud Eureka Service

Once the discovery server is ready, now we let us create our microservice. Again this will be spring boot app and we will be using spring boot starter to download the sample project.

spring-cloud-netflix-service

Here is the pom file.

pom.xml
<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</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>

This module will act as a microservice and upon start it will register itself to the discovery server.For this registration, we need to configure in application.properties about the discovery server.Below are the entries.spring.application.name iss the unique identifier for this service and eureka.client.service-url.defaultZone is the url of service discvery server.

spring.application.name=eureka-service
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
server.port=8085

To configure this application as a eureka service and a client for discovery server, we need to annotate our spring boot application with @EnableDiscoveryClient

package com.devglan.eurekaservice;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@SpringBootApplication
public class EurekaServiceApplication {

	public static void main(String[] args) {
		SpringApplication.run(EurekaServiceApplication.class, args);
	}
}

Following is the controller class where we have exposed our microservices for the client applications.

GreetingController.java
package com.devglan.eurekaservice.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreetingController {

    @GetMapping("/")
    public String greeting(){
        return "Hello from" ;
    }


}

Spring Cloud Eureka Client

Now, it's time to define our client.For this again we will have following project generated using spring starter.

spring-cloud-netflix-client

This client will interact with the eureka service discovery server and discover the service using eureka client and then consume the micro services exposed by our service implementation above.Following is the sample pom.xml file.

pom.xml
<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-eureka</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>

Following entries are required in application.properties file. Since, this is a client project hence we don&pos;s want it to register to the discovery server. But there can be scenarios where an application can be a client and server both.In that case, eureka.client.register-with-eureka will be true.

application.properties
spring.application.name=eureka-client
eureka.client.service-url.defaultZone=http://localhost:8761/eureka
eureka.client.register-with-eureka=false

Following will be our Application class. It is annotated with @EnableDiscoveryClient to register this application as a discovery client.

package com.devglan.eurekaclient;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@EnableDiscoveryClient
@SpringBootApplication
public class EurekaClientApplication {

	public static void main(String[] args) {
		SpringApplication.run(EurekaClientApplication.class, args);
	}
}

Now, we will be defining our controller, which will have one API exposed at the root level. This API will discover the services from discovery server and invoke the service.Here, we have autowired the eureka client and getNextServerFromEureka() accepts two parameter. The first parameter is the service identifer of the microervices application. Our above service implementation has register itself with the discovery client with this name eureka-service and the same name will be used by the eureka client application to discover the service.

Once this service is discovered, the client will invoke the microservices.Remeber that we have exposed one greeting API in the service implementation above and the same API will be invoked by the client.

ClientController.java

package com.devglan.eurekaclient.controller;

import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class ClientController {

    @Autowired
    private EurekaClient eurekaClient;

    @Autowired
    private RestTemplateBuilder restTemplateBuilder;

    @GetMapping("/")
    public String invokeService(){
        RestTemplate restTemplate = restTemplateBuilder.build();
        InstanceInfo instanceInfo = eurekaClient.getNextServerFromEureka("eureka-service", false);
        String serviceBaseUrl = instanceInfo.getHomePageUrl();
        return restTemplate.getForObject(serviceBaseUrl, String.class);
    }
}

Testing the Application

To test the application, first start the discovery server. To do so, we need to run DiscoveryServerApplication.java as a java application. You can check the console and find similar logs as below. You can also see the url http://localhost:8761/eureka/ in the console exposed by discovery server to register the services.

spring-cloud-netflix-discovery-server-log

Now, start the service.Run EurekaServiceApplication.java as a java application. You can also run multiple instances of this service.All the instances will be registered with the discovery server.On successfull registration of the service, you will get 204 response from discovery client.

spring-cloud-netflix-service-log

Now, in similar fashion start the client by running EurekaClientApplication.java as a java application.

Now hit the url http://localhost:8080 to check the string response as Hello from from the eureka service app.

Spring Cloud Eureka Dashboard

You might have noticed in the application.properties file in the discovery server implementation that the port we configured is 8761. On this port, Spring cloud eureka provides a dashboard which is enabled by default that displays useful metadata and serice status.Here we can check info about discovery server replicas which in our case is 1 that is running on localhost.Similarly, we have info about the registred service with the discovery server with the current status.

spring-cloud-netflix-eureka-dashboard

Conclusion

In this tutorial, we learned about the spring cloud netflix eureka implementation. We implemented discovery server, application service and application client.The source can be downloaded from here.If you have anything that you want to add or share then please share it below in the comment section

Further Reading on Spring Cloud

1. Spring Netflix Zuul

2. Introduction To Microservices

3. Spring Cloud Config

4. Refresh Property Config Runtime

5. Encrypt Decrypt Cloud Config Properties

If You Appreciate What We Do Here On Devglan, You Should Consider: