DEV Community

Said Olano
Said Olano

Posted on

Netflix Eureka: Service Discovery in Action (2026-08-18 14:31)

Netflix Eureka: Service Discovery in Action

In a monolithic application, components talk to each other through in-process method calls. But once you break your system into microservices, those components live on different hosts, scale up and down dynamically, and get assigned ephemeral network addresses. How does one service find another when IP addresses are constantly changing?

This is the problem service discovery solves, and Netflix Eureka is one of the most battle-tested tools for the job.

What Is Eureka?

Eureka is a REST-based service registry originally built by Netflix and later open-sourced as part of the Netflix OSS stack. It has two main components:

  • Eureka Server — the registry where services announce their presence.
  • Eureka Client — embedded in each microservice; it registers the service on startup and periodically fetches the registry to discover peers.

The core idea is simple: instead of hardcoding hostnames and ports, services ask the registry "where is service X?" and get back a list of healthy instances.

The Registration Lifecycle

Understanding Eureka means understanding its lifecycle:

  1. Registration — When a client starts, it POSTs its metadata (host, port, health URL, etc.) to the Eureka Server.
  2. Renewal (Heartbeat) — The client sends a heartbeat every 30 seconds (by default) to prove it's alive.
  3. Fetch Registry — Clients pull the full registry (every 30 seconds) and cache it locally.
  4. Cancellation — On graceful shutdown, the client sends a cancel request to deregister.
  5. Eviction — If the server misses heartbeats past the eviction threshold, it removes the instance.

Setting Up a Eureka Server

With Spring Cloud, standing up a Eureka Server is remarkably lean. Add the dependency:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Then enable it in your main application class:

@SpringBootApplication
@EnableEurekaServer
public class DiscoveryServerApplication {
    public static void main(String[] args) {
        SpringApplication.run(DiscoveryServerApplication.class, args);
    }
}
Enter fullscreen mode Exit fullscreen mode

Configure application.yml so the server doesn't try to register with itself:

server:
  port: 8761

eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
  server:
    enable-self-preservation: true
Enter fullscreen mode Exit fullscreen mode

Boot it up and visit http://localhost:8761 to see the Eureka dashboard.

Registering a Client

Any microservice becomes discoverable by adding the client starter:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
Enter fullscreen mode Exit fullscreen mode

And pointing it at the server:

spring:
  application:
    name: order-service

eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
Enter fullscreen mode Exit fullscreen mode

The spring.application.name becomes the service ID other services use to look it up.

Discovering and Calling Services

Once registered, you can call other services by name rather than by URL. With a load-balanced RestTemplate:

@Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}
Enter fullscreen mode Exit fullscreen mode
@Service
public class InventoryClient {

    private final RestTemplate restTemplate;

    public InventoryClient(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public Inventory checkStock(String sku) {
        // "inventory-service" is resolved via Eureka
        return restTemplate.getForObject(
            "http://inventory-service/api/stock/" + sku,
            Inventory.class);
    }
}
Enter fullscreen mode Exit fullscreen mode

Notice there's no IP or port—Spring Cloud LoadBalancer resolves inventory-service to a live instance and distributes calls across all healthy nodes.

Self-Preservation Mode: A Common Gotcha

Eureka has a feature called self-preservation that catches many engineers off guard. If the server suddenly stops receiving the expected number of heartbeats (below ~85% within a window), it assumes there's a network partition rather than mass service failure. Instead of evicting instances, it preserves the registry to avoid wrongly removing healthy services.

This is a deliberate design choice rooted in the CAP theorem: Eureka favors availability over consistency. It would rather serve slightly stale registry data than risk removing instances that are actually reachable.

In development, self-preservation can be confusing because dead instances linger. You can disable it locally:

eureka:
  server:
    enable-self-preservation: false
    eviction-interval-timer-in-ms: 5000
Enter fullscreen mode Exit fullscreen mode

But keep it enabled in production—it's a safety net for real network turbulence.

High Availability with Peer Awareness

A single Eureka Server is a single point of failure. In production, run multiple servers that register with each other (peer awareness):

# Instance running as peer1
eureka:
  instance:
    hostname: peer1
  client:
    service-url:
      defaultZone: http://peer2:8761/eureka/,http://peer3:8761/eureka/
Enter fullscreen mode Exit fullscreen mode

Each server replicates its registry to its peers, so if one node fails, clients seamlessly fall back to another.

When Should You Use Eureka?

Eureka shines in JVM-heavy, Spring Cloud ecosystems where client-side load bal

Top comments (0)