Service Registry with Eureka
Service Registry with Eureka
In the previous lesson you saw why hard-coding service addresses breaks down as soon as you run more than one instance of anything. A service registry is the solution: a central store where every service instance announces itself on startup and deregisters on shutdown. Any caller can then ask the registry for a live address instead of having it baked into a config file.
Spring Cloud ships first-class support for Netflix Eureka, which has been battle-tested in large-scale production systems. Eureka follows a simple model: a dedicated Eureka Server holds the registry, and each microservice runs a Eureka Client that registers, renews a heartbeat, and fetches the registry for use by client-side load balancing.
Standing Up the Eureka Server
Start a new Spring Boot 3 project and add two dependencies:
Then annotate the main class with @EnableEurekaServer:
The server needs a minimal application.yml that tells it not to register with itself (it is the registry, not a client):
Run the server and open http://localhost:8761. You will see the Eureka dashboard — currently empty, ready for registrations.
eureka.client.service-url in development, which removes a whole class of misconfiguration.
Registering a Service: The Eureka Client
Every service that wants to be discoverable adds the client starter:
No annotation is needed in Spring Boot 3 / Spring Cloud 2023 — presence of the starter on the classpath activates auto-configuration. All you need is the service name in application.yml:
Start this service and refresh the Eureka dashboard. You will see ORDER-SERVICE appear in the "Instances currently registered with Eureka" table with its IP, port, and status UP.
What Happens at Registration Time
When the Eureka client starts it performs an HTTP POST to /eureka/apps/{appName} on the server, sending a JSON payload called an InstanceInfo. This contains:
- Application name (
order-service, uppercased) - Host and port
- Health-check URL (defaults to the Spring Boot Actuator
/actuator/healthendpoint if present) - Status — initially
STARTING, thenUPonce the context is ready - Metadata map — arbitrary key-value pairs you can use for routing hints
After registration, the client sends a PUT heartbeat (renewal) every lease-renewal-interval-in-seconds seconds. If the server receives no renewal within lease-expiration-duration-in-seconds seconds it marks the instance DOWN and eventually evicts it.
Discovering Services Programmatically
Once a service is registered, any other Eureka client in the same cluster can resolve it by name. The simplest way is DiscoveryClient, injected by Spring:
The getInstances() call returns every live instance registered under that name. The URI is already fully assembled from the instance metadata. In practice you rarely call DiscoveryClient directly — you let Spring Cloud LoadBalancer (covered in the next lesson) pick an instance for you — but understanding the raw API is essential for debugging and for custom routing logic.
Security Considerations for the Registry
The Eureka dashboard and REST API are unauthenticated by default. In any environment where the registry is reachable from untrusted networks this is a critical misconfiguration: a malicious client could register a fake instance and redirect traffic to it (a service-spoofing attack).
The standard mitigation is to add Spring Security to the Eureka Server project and require HTTP Basic authentication, then embed the credentials in the client URLs:
Self-Preservation Mode
Eureka has a built-in mechanism called self-preservation mode. If the server stops receiving renewals from a significant fraction of registered instances (above a configurable threshold), it assumes the network is experiencing a partition rather than that all those services have gone down, and it stops evicting instances. This preserves stale but potentially still-live entries rather than emptying the registry during a network blip.
Self-preservation is appropriate for production but can be confusing in development, where stopping a service should immediately remove it. You can disable it per environment:
Summary
A Eureka Server is a single Spring Boot application annotated with @EnableEurekaServer. Each client service adds the Eureka client starter and sets spring.application.name; registration and heartbeating are automatic. Other services discover live instances by name via DiscoveryClient or, more practically, through Spring Cloud LoadBalancer. Always secure the registry endpoint with credentials and TLS in any non-local environment, and understand self-preservation mode so it does not surprise you during incidents.