What You Will Build
You will set up a Netflix Eureka service registry and then build a client that both registers itself with the registry and uses it to resolve its own host. A service registry is useful because it enables client-side load-balancing and decouples service providers from consumers without the need for DNS.
What You Need
- About 15 minutes
- A favorite text editor or IDE
- JDK 1.8 or later
- Gradle 4+ or Maven 3.2+
- You can also import the code straight into your IDE:
How to complete this guide
Like most Spring Getting Started guides, you can start from scratch and complete each step or you can bypass basic setup steps that are already familiar to you. Either way, you end up with working code.
To start from scratch, move on to Starting with Spring Initializr.
To skip the basics, do the following:
Download and unzip the source repository for this guide, or clone it using Git:
git clone https://github.com/spring-guides/gs-service-registration-and-discovery.git
cd into
gs-service-registration-and-discovery/initial
Jump ahead to Start a Eureka Service Registry.
When you finish, you can check your results against the code in
gs-service-registration-and-discovery/complete
.
Starting with Spring Initializr
For all Spring applications, you should start with the Spring Initializr. The Initializr offers a fast way to pull in all the dependencies you need for an application and does a lot of the set up for you.
This guide needs two applications. The first application (the service application) needs only the Eureka Server dependency. The following image shows the Initializr set up for the service application:

The preceding image shows the Initializr with Maven chosen as the build tool. You can also use Gradle. It also shows values of
com.example
andservice-registration-and-discovery-service
as the Group and Artifact, respectively. You will use those values throughout the rest of this sample.
The following listing shows the
pom.xml
file (for the service application) that is created when you choose Maven:
<?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 https://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.2.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>service-registration-and-discovery-service</artifactId> <version>0.0.1-SNAPSHOT</version> <name>service-registration-and-discovery-service</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.SR1</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> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </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> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> </project>
The following listing shows the
build.gradle
file (for the service application) that is created when you choose Gradle:
plugins { id 'org.springframework.boot' version '2.2.2.RELEASE' id 'io.spring.dependency-management' version '1.0.8.RELEASE' id 'java' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' repositories { mavenCentral() maven { url 'https://repo.spring.io/milestone' } } ext { set('springCloudVersion', "Hoxton.SR1") } dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server' testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } } dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" } } test { useJUnitPlatform() }
The second application (the client application) needs the Eureka Server and Eureka Discovery Client dependencies. The following image shows the Initializr set up for the client application:

The preceding image shows the Initializr with Maven chosen as the build tool. You can also use Gradle. It also shows values of
com.example
andservice-registration-and-discovery-service
as the Group and Artifact, respectively. You will use those values throughout the rest of this sample.
The following listing shows the
pom.xml
file (for the client application) that is created when you choose Maven:
<?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 https://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.2.2.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>service-registration-and-discovery-client</artifactId> <version>0.0.1-SNAPSHOT</version> <name>service-registration-and-discovery-client</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>Hoxton.SR1</spring-cloud.version> </properties> <dependencies> <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-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </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> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> </project>
The following listing shows the
build.gradle
file (for the client application) that is created when you choose Gradle:
plugins { id 'org.springframework.boot' version '2.2.2.RELEASE' id 'io.spring.dependency-management' version '1.0.8.RELEASE' id 'java' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' repositories { mavenCentral() maven { url 'https://repo.spring.io/milestone' } } ext { set('springCloudVersion', "Hoxton.SR1") } dependencies { implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client' implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server' testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } } dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" } } test { useJUnitPlatform() }
For convenience, we have provided build files (a
pom.xml
file and abuild.gradle
file) at the top of the project (one directory above theservice
andclient
directories) that you can use to build both projects at once. We also added the Maven and Gradle wrappers there.
Start a Eureka Service Registry
You first need a Eureka Service registry. You can use Spring Cloud’s
@EnableEurekaServer
to stand up a registry with which other applications can communicate. This is a regular Spring Boot application with one annotation (@EnableEurekaServer
) added to enable the service registry. The following listing (fromeureka-service/src/main/java/com.example.serviceregistrationanddiscoveryservice/ServiceRegistrationAndDiscoveryServiceApplication.java
) shows the service application:
package com.example.serviceregistrationanddiscoveryservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class ServiceRegistrationAndDiscoveryServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceRegistrationAndDiscoveryServiceApplication.class, args);
}
}
When the registry starts, it will complain (with a stacktrace) that there are no replica nodes to which the registry can connect. In a production environment, you will want more than one instance of the registry. For our simple purposes, however, it suffices to disable the relevant logging.
By default, the registry also tries to register itself, so you need to disable that behavior as well.
It is a good convention to put this registry on a separate port when using it locally.
Add some properties to
eureka-service/src/main/resources/application.properties
to handle all of these requirements, as the following listing shows:
server.port=8761
eureka.client.register-with-eureka=false
eureka.client.fetch-registry=false
logging.level.com.netflix.eureka=OFF
logging.level.com.netflix.discovery=OFF
Talking to the Registry
Now that you have started a service registry, you can stand up a client that both registers itself with the registry and uses the Spring Cloud
DiscoveryClient
abstraction to interrogate the registry for its own host and port. The@EnableDiscoveryClient
activates the Netflix EurekaDiscoveryClient
implementation. (There are other implementations for other service registries, such as Hashicorp’s Consul or Apache Zookeeper). The following listing (fromeureka-client/src/main/java/example/serviceregistrationanddiscoveryclient/ServiceRegistrationAndDiscoveryClientApplication.java
) shows the client application:
package com.example.serviceregistrationanddiscoveryclient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@EnableDiscoveryClient
@SpringBootApplication
public class ServiceRegistrationAndDiscoveryClientApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceRegistrationAndDiscoveryClientApplication.class, args);
}
}
@RestController
class ServiceInstanceRestController {
@Autowired
private DiscoveryClient discoveryClient;
@RequestMapping("/service-instances/{applicationName}")
public List<ServiceInstance> serviceInstancesByApplicationName(
@PathVariable String applicationName) {
return this.discoveryClient.getInstances(applicationName);
}
}
Whatever implementation you choose, you should soon see
eureka-client
registered under whatever name you specify in thespring.application.name
property. This property is used a lot in Spring Cloud, often in the earliest phases of a service’s configuration. This property is used in service bootstrap and, so, by convention lives ineureka-client/src/main/resources/bootstrap.properties
where it is found beforesrc/main/resources/application.properties
. The following listing shows thebootstrap.properties
file:
spring.application.name=a-bootiful-client
The
eureka-client
defines a Spring MVC REST endpoint (ServiceInstanceRestController
) that returns an enumeration of all the registeredServiceInstance
instances athttp://localhost:8080/service-instances/a-bootiful-client
. See the Building a RESTful Web Service guide to learn more about building REST services with Spring MVC and Spring Boot.
Test the Application
Test the end-to-end result by starting the
eureka-service
first and then, once that has loaded, starting theeureka-client
.
To run the Eureka service with Maven, run the following command in a terminal window (in the
/complete
directory):
./mvnw spring-boot:run -pl eureka-service
To run the Eureka client with Maven, run the following command in a terminal window (in the
/complete
directory):
./mvnw spring-boot:run -pl eureka-client
To run the Eureka service with Gradle, run the following command in a terminal window (in the
/complete
directory):
./gradlew :eureka-service:bootRun
To run the Eureka client with Gradle, run the following command in a terminal window (in the
/complete
directory):
./gradlew :eureka-client:bootRun
The
eureka-client
will take about a minute to register itself in the registry and to refresh its own list of registered instances from the registry. Visit theeureka-client
in the browser, athttp://localhost:8080/service-instances/a-bootiful-client
. There, you should see theServiceInstance
for theeureka-client
reflected in the response. If you see an empty<List>
element, wait a bit and refresh the page.
Summary
Congratulations! You have just used Spring to stand up a Netflix Eureka service registry and to use that registry in a client application.