Service discovery allows microservices to find and communicate with each other without hardcoded URLs. Spring Cloud supports Eureka, Consul, and Kubernetes-native discovery.

Eureka Server

  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
  
  @SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication { }
  
  server:
  port: 8761
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
  

Eureka Client

  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
  
  spring:
  application:
    name: order-service
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true
    lease-renewal-interval-in-seconds: 30
  
  @SpringBootApplication
@EnableDiscoveryClient
public class OrderApplication { }
  

Calling Services by Name

With OpenFeign:

  @FeignClient(name = "user-service")
public interface UserClient {
    @GetMapping("/api/users/{id}")
    UserDto getUser(@PathVariable Long id);
}
  

With RestTemplate + @LoadBalanced:

  @Bean
@LoadBalanced
public RestTemplate restTemplate() {
    return new RestTemplate();
}

// Usage: http://user-service/api/users/1 (resolved via Eureka)
UserDto user = restTemplate.getForObject(
    "http://user-service/api/users/{id}", UserDto.class, 1L);
  

With WebClient:

  @Bean
@LoadBalanced
public WebClient.Builder webClientBuilder() {
    return WebClient.builder();
}

webClientBuilder.build()
    .get()
    .uri("http://user-service/api/users/{id}", userId)
    .retrieve()
    .bodyToMono(UserDto.class);
  

Health and Eureka

  eureka:
  client:
    healthcheck:
      enabled: true
management:
  endpoint:
    health:
      show-details: always
  

Kubernetes Alternative

In Kubernetes, use native service discovery instead of Eureka:

  spring:
  cloud:
    kubernetes:
      discovery:
        enabled: true
  

Services are discovered via Kubernetes DNS: http://user-service.default.svc.cluster.local.

Best Practices

  • Run Eureka in HA mode (multiple server instances) in production
  • Use prefer-ip-address: true in containerized environments
  • Prefer Kubernetes-native discovery when running on K8s
  • Combine service discovery with client-side load balancing (Spring Cloud LoadBalancer)
  • Monitor Eureka dashboard for unhealthy instances