Service Discovery with Eureka in Spring Cloud: Complete Implementation Guide
Eureka provides a REST-based service registry that handles automatic service registration, heartbeat-driven health checks, and client-side service discovery for Spring Cloud microservices architectures.
This guide explains how to implement service discovery with Eureka in Spring Cloud using the doocs/advanced-java repository as a reference. You will learn the internal mechanics of the Eureka server, registration lifecycle, and practical configuration steps for production-ready microservices.
How Eureka Service Discovery Works
Eureka is the service registry component within Spring Cloud Netflix. It maintains a dynamic directory of all running microservice instances and enables clients to locate services without hardcoded URLs. The architecture consists of two primary roles:
- Eureka Server – The central registry that stores service instance metadata and handles registration queries. Annotated with
@EnableEurekaServer. - Eureka Client – Any microservice that registers itself (service provider) or queries the registry (service consumer). Annotated with
@EnableEurekaClient.
According to the doocs/advanced-java documentation in docs/micro-services/how-eureka-enable-service-discovery-and-service-registration.md, the entire process follows a RESTful HTTP protocol with specific endpoints for registration, renewal, and discovery.
Service Registration Flow
When a Spring Boot application starts with Eureka Client enabled, it executes the following registration sequence:
- Initial Registration – The client sends a POST request to
ApplicationResource.addInstanceon the Eureka server. The payload includes instance metadata such as IP address, port, health-check URL, and custom metadata. - Registry Storage – The server delegates to
PeerAwareInstanceRegistryImpl.register, which stores the instance in a nestedMapstructure keyed by application name and instance ID. - Peer Replication – The registration is asynchronously replicated to peer Eureka servers via the
replicateToPeersmethod to ensure high availability across the cluster.
Heartbeat Mechanism and Health Checks
Eureka uses a lease-based model to track instance health. Every client must periodically renew its registration:
- The client issues a PUT request to
InstanceResource.renewLeaseeveryeureka.instance.lease-renewal-interval-in-seconds(default 30 seconds). - The server updates the lease timestamp and replicates the renewal to peer nodes.
- If the server does not receive a renewal within
eureka.instance.leaseExpirationDurationInSeconds(default 90 seconds), the instance becomes eligible for eviction.
Instance Eviction and Failover
A background evictionTimer task runs every eureka.server.evictionIntervalTimerInMs (default 60 seconds) to remove expired instances:
- Instances that fail to renew their lease within the expiration window are evicted from the registry.
- Consumers automatically stop receiving traffic for evicted instances, enabling rapid failover.
- The eviction process is replicated across the peer-to-peer cluster to maintain consistency.
Service Discovery Flow for Consumers
Service consumers interact with Eureka to locate provider instances:
- Initial Fetch – On startup, the client calls
DiscoveryClient.fetchRegistry, which sends a GET request toInstanceResourceto retrieve the complete registry snapshot. - Local Caching – The client caches the registry locally in memory to minimize network overhead.
- Periodic Refresh – Every
eureka.client.registry-fetch-interval-seconds(default 30 seconds), the client re-fetches the registry to update its cache with new or removed instances.
Implementing the Eureka Server
To create a standalone Eureka Server, add the Spring Cloud Netflix dependency and enable the server annotation.
Maven Dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
Application Class:
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
Application Configuration:
server:
port: 8761
eureka:
client:
register-with-eureka: false
fetch-registry: false
server:
eviction-interval-timer-in-ms: 60000
Setting register-with-eureka and fetch-registry to false prevents the server from attempting to register with itself.
Registering Microservices with Eureka Client
Service providers must include the Eureka Client dependency and configure their registration behavior.
Maven Dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
Application Class:
@SpringBootApplication
@EnableEurekaClient
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}
Application Configuration:
server:
port: 8081
spring:
application:
name: service-provider
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
lease-renewal-interval-in-seconds: 30
lease-expiration-duration-in-seconds: 90
The spring.application.name becomes the logical service ID used for discovery. Adjust lease-renewal-interval-in-seconds to control heartbeat frequency based on your network reliability requirements.
Consuming Services with DiscoveryClient
Consumers use the same Eureka Client dependency but focus on fetching registry information rather than publishing their own.
Application Configuration:
spring:
application:
name: service-consumer
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
fetch-registry: true
registry-fetch-interval-seconds: 30
RestTemplate Configuration with Ribbon:
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
Service Invocation:
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/call")
public String callProvider() {
return restTemplate.getForObject("http://service-provider/hello", String.class);
}
}
The @LoadBalanced annotation enables client-side load balancing through Ribbon. When using the logical service name service-provider in the URL, Ribbon queries the local Eureka cache, selects an available instance, and replaces the hostname with the actual IP and port.
Summary
- Eureka Server acts as the central registry using
PeerAwareInstanceRegistryImplto store instance data in memory-mapped structures and replicate changes viareplicateToPeers. - Registration occurs via POST to
ApplicationResource.addInstanceon startup, followed by periodic PUT requests toInstanceResource.renewLeasefor heartbeats. - Service Discovery relies on
DiscoveryClient.fetchRegistryto cache the registry locally and refresh every 30 seconds by default. - Eviction removes unhealthy instances after 90 seconds of missed heartbeats, executed by the
evictionTimertask. - Spring Cloud abstracts HTTP interactions, requiring only
@EnableEurekaClientand configuration properties to enable full service discovery capabilities.
Frequently Asked Questions
What is the default heartbeat interval for Eureka clients?
Eureka clients send heartbeat renewals every 30 seconds by default, controlled by the eureka.instance.lease-renewal-interval-in-seconds property. The server considers an instance expired if it misses renewals for 90 seconds (configurable via lease-expiration-duration-in-seconds).
How does Eureka handle server failures in a cluster?
Eureka servers replicate registration and renewal events to peer nodes asynchronously using the replicateToPeers method. If one server fails, clients automatically failover to other nodes configured in eureka.client.service-url.defaultZone, while cached registry data allows continued operation during brief outages.
Can a microservice be both a provider and a consumer in Eureka?
Yes. Any application annotated with @EnableEurekaClient simultaneously registers itself as a provider (via ApplicationResource.addInstance) and can discover other services (via DiscoveryClient.fetchRegistry). The dual role requires no additional configuration beyond standard Eureka Client setup.
Where is the complete architectural documentation for Eureka in the doocs/advanced-java repository?
The complete sequence diagrams and registry structure details are documented in docs/micro-services/how-eureka-enable-service-discovery-and-service-registration.md within the doocs/advanced-java repository, which illustrates the interaction between PeerAwareInstanceRegistryImpl, ApplicationResource, and InstanceResource.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →