Service Discovery — Eureka
IntermediateService instances register with a registry (Eureka, Consul) on startup; clients query the registry or use client-side load balancing (Ribbon/Spring Cloud LoadBalancer) to resolve addresses.
Overview
In a microservices architecture, service instances are ephemeral — they start and stop dynamically as deployments roll out, pods scale, or failures occur. Hard-coding IP addresses or hostnames is brittle. Service discovery solves this by maintaining a live registry of available service instances. Two flavours exist: client-side discovery (e.g., Eureka + Spring Cloud LoadBalancer), where the client queries the registry and picks an instance; and server-side discovery (e.g., Kubernetes Services, AWS ALB), where a load balancer proxy sits between clients and instances. In the Spring ecosystem, Netflix Eureka is the classic choice; in Kubernetes-native deployments, DNS-based discovery via K8s Services replaces it entirely.
How Eureka Works — Registration, Heartbeat, and Renewal
Each service instance is an Eureka client. On startup it registers itself (appName, IP, port, health URL) with the Eureka Server. Every 30 seconds (default) it sends a heartbeat renewal. If the server receives no renewal for 90 seconds, it evicts the instance. Clients fetch the full registry from the server on startup and cache it locally, refreshing every 30 seconds (configurable). This means there is a propagation delay — a newly started instance may not be visible to clients for up to 60 seconds.
<!-- Eureka Server — standalone registry -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
@SpringBootApplication
@EnableEurekaServer
public class DiscoveryServer { }
# application.yml — Eureka Server
server.port: 8761
eureka:
client:
register-with-eureka: false # the server doesn't register itself
fetch-registry: false
---
<!-- Eureka Client — every microservice -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
# application.yml — Microservice
spring.application.name: order-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka
instance:
prefer-ip-address: true # register with IP, not hostname
lease-renewal-interval-in-seconds: 30
lease-expiration-duration-in-seconds: 90Client-Side Load Balancing with Spring Cloud LoadBalancer
Once instances are registered in Eureka, callers use Spring Cloud LoadBalancer (the modern replacement for Ribbon) to resolve `lb://service-name` URIs to actual instance addresses. It fetches the registry, applies a load balancing algorithm (round-robin by default), and routes the request. Use it with WebClient or OpenFeign.
// WebClient with load balancer — uses lb:// URI
@Configuration
public class WebClientConfig {
@Bean
@LoadBalanced // ← enables lb:// URI resolution via Eureka
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
}
@Service
@RequiredArgsConstructor
public class OrderClient {
private final WebClient.Builder webClientBuilder;
public Mono<PaymentResponse> getPayment(String paymentId) {
return webClientBuilder
.baseUrl("lb://payment-service") // Eureka resolves this
.build()
.get()
.uri("/payments/{id}", paymentId)
.retrieve()
.bodyToMono(PaymentResponse.class);
}
}
// OpenFeign — even simpler
@FeignClient(name = "payment-service") // name matches spring.application.name
public interface PaymentClient {
@GetMapping("/payments/{id}")
PaymentResponse getPayment(@PathVariable String id);
}Kubernetes-Native Discovery — No Eureka Needed
In Kubernetes, each Service object provides stable DNS and load-balanced VIP in front of Pods. Service discovery is handled by kube-dns/CoreDNS — call http://payment-service:8080 and Kubernetes routes to a healthy pod. No Eureka server is needed. For Spring Cloud apps deployed to K8s, use Spring Cloud Kubernetes which integrates directly with the K8s API server for service resolution instead of Eureka.
# Kubernetes Service — built-in discovery
apiVersion: v1
kind: Service
metadata:
name: payment-service # DNS name usable by other pods
namespace: production
spec:
selector:
app: payment-service # matches pods with this label
ports:
- port: 8080
targetPort: 8080
type: ClusterIP # internal-only load balancer
# Any pod in the cluster can call:
# http://payment-service.production.svc.cluster.local:8080
# http://payment-service:8080 (same namespace)
# Spring Boot app.yml for K8s — just use the K8s DNS name
payment:
service-url: http://payment-service:8080
# Or use Spring Cloud Kubernetes for registry-aware lb://
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-kubernetes-client-loadbalancer</artifactId>
</dependency>Key Points to Remember
- 1Client-side discovery (Eureka + LoadBalancer): client fetches registry and picks instance. Server-side discovery (K8s Service, ALB): proxy picks instance.
- 2Eureka heartbeat: 30 s; eviction timeout: 90 s — newly registered instances can take up to 60 s to become visible to all clients.
- 3Spring Cloud LoadBalancer replaces the deprecated Ribbon; use @LoadBalanced WebClient or OpenFeign with lb:// URIs.
- 4In Kubernetes, kube-dns provides built-in service discovery via ClusterIP Services — no Eureka server needed.
- 5Spring Cloud Kubernetes integrates with the K8s API server for service discovery in cloud-native deployments.
- 6Always configure health checks (Actuator /health) so the registry removes unhealthy instances before they receive traffic.
Interview Questions
Sign in to ask AriaWhat is the difference between client-side and server-side service discovery?
How does Eureka know when to evict a service instance?
A newly deployed service instance is not receiving traffic for 60 seconds. Why?
Why do you not need Eureka in a Kubernetes-native microservices deployment?
How would you implement a custom load balancing strategy with Spring Cloud LoadBalancer?
Ask Aria about Service Discovery — Eureka
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.