Java Notes
Setting up Netflix Eureka Server for service discovery in Spring Boot microservices - server configuration, client registration, and service communication.
What is Service Discovery?
In a monolithic application, all modules live in one deployable unit — they communicate through direct method calls. But in a microservices architecture, services are independent processes running on different ports or even different machines. The fundamental problem becomes: how does Service A find and communicate with Service B?
You could hardcode URLs like http://localhost:8081, but what happens when:
- Service B moves to a different port or server?
- You deploy multiple instances of Service B for load balancing?
- An instance of Service B crashes and a new one starts?
Service Discovery solves this by maintaining a dynamic registry of all running service instances. Services register themselves when they start and deregister when they stop. Other services query the registry to find available instances.
Netflix Eureka is the most popular service discovery solution in the Spring Cloud ecosystem. It provides both the registry server and the client library that Spring Boot applications use to register and discover services.
Setting Up Eureka Server
Step 1: Create Spring Boot Project
Add the Eureka Server dependency in your pom.xml:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.4</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2023.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>Step 2: Enable Eureka Server
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}The @EnableEurekaServer annotation transforms this Spring Boot application into a service registry.
Step 3: Configure application.yml
server:
port: 8761 # Default Eureka port
eureka:
client:
register-with-eureka: false # Server does not register with itself
fetch-registry: false # Server does not need to fetch from itself
server:
enable-self-preservation: false # Disable in development
eviction-interval-timer-in-ms: 5000 # Check for dead instances every 5sAfter starting the application, visit http://localhost:8761 to see the Eureka dashboard showing all registered services.
Registering Eureka Clients
Every microservice that wants to participate in service discovery needs the Eureka Client dependency:
Client pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>Client application.yml
spring:
application:
name: user-service # This name appears in the Eureka registry
server:
port: 8081
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true # Register with IP instead of hostname
lease-renewal-interval-in-seconds: 10 # Heartbeat frequency
lease-expiration-duration-in-seconds: 30 # Considered dead after thisThe spring.application.name is critical — this is the service name other services will use to discover and communicate with this service.
Service-to-Service Communication
Using RestTemplate with @LoadBalanced
@Configuration
public class AppConfig {
@Bean
@LoadBalanced // Enables service name resolution via Eureka
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
@Service
@RequiredArgsConstructor
public class OrderService {
private final RestTemplate restTemplate;
public UserDTO getUserForOrder(Long userId) {
// Uses SERVICE NAME instead of hostname:port!
// Eureka resolves "USER-SERVICE" to actual running instance
return restTemplate.getForObject(
"http://USER-SERVICE/api/users/" + userId, UserDTO.class);
}
}The @LoadBalanced annotation intercepts the RestTemplate call, looks up "USER-SERVICE" in the local Eureka registry cache, selects one instance (round-robin by default), and replaces the service name with the actual IP:port.
Using OpenFeign (Recommended Approach)
OpenFeign provides a declarative, interface-based HTTP client that is cleaner and more maintainable:
// Add dependency: spring-cloud-starter-openfeign
// Enable on main class: @EnableFeignClients
@FeignClient(name = "USER-SERVICE") // Service name in Eureka
public interface UserClient {
@GetMapping("/api/users/{id}")
UserDTO getUserById(@PathVariable Long id);
@GetMapping("/api/users")
List<UserDTO> getAllUsers();
@PostMapping("/api/users")
UserDTO createUser(@RequestBody UserDTO user);
}
@Service
@RequiredArgsConstructor
public class OrderService {
private final UserClient userClient; // Injected like any Spring bean
public OrderDTO createOrder(OrderRequest request) {
UserDTO user = userClient.getUserById(request.getUserId());
// Create order with user details...
return new OrderDTO(user, request.getItems());
}
}Feign handles service discovery, load balancing, serialization, and error handling automatically. You just define the interface and Spring generates the implementation.
Self-Preservation Mode
Eureka has a safety mechanism called self-preservation mode. If Eureka detects that more than 85% of registered services have stopped sending heartbeats, it assumes a network partition has occurred (not that all services died) and stops evicting instances.
Why? During a network issue between Eureka and its clients, the services might still be healthy and serving users — they just cannot reach Eureka. Evicting them would cause unnecessary disruption.
In development: Disable self-preservation (enable-self-preservation: false) so dead instances are removed quickly during testing.
In production: Keep self-preservation enabled for resilience against network partitions.
High Availability (Eureka Cluster)
A single Eureka server is a single point of failure. For production, run multiple Eureka instances that replicate their registries to each other:
# Eureka Server 1 (port 8761)
eureka:
client:
service-url:
defaultZone: http://eureka2:8762/eureka/
# Eureka Server 2 (port 8762)
eureka:
client:
service-url:
defaultZone: http://eureka1:8761/eureka/Each server registers with the other(s). Client services register with ALL Eureka servers for redundancy.
Interview Key Points
| Concept | Key Fact |
|---|---|
| Registration | Clients register on startup, send heartbeats every 30s |
| Discovery | Clients cache the registry locally, refresh every 30s |
| Load Balancing | @LoadBalanced enables round-robin across instances |
| Self-Preservation | Prevents mass eviction during network partitions |
| Feign | Declarative HTTP client for service-to-service calls |
| High Availability | Multiple Eureka servers replicate to each other |
| Default Port | 8761 (convention, not requirement) |
| Health Checks | /actuator/health endpoint monitored by Eureka |
Eureka vs Alternatives
| Feature | Eureka | Consul | Zookeeper |
|---|---|---|---|
| Spring Cloud Integration | Native | Good | Fair |
| Health Checking | Client heartbeat | HTTP/TCP/Script | Session-based |
| Consistency Model | AP (Available) | CP (Consistent) | CP (Consistent) |
| Key-Value Store | No | Yes | Yes |
| Multi-datacenter | Limited | Native | Complex |
| Setup Complexity | Simple | Moderate | Complex |
When to choose Eureka: You are building Spring Boot microservices and want the simplest setup with native Spring Cloud support. Eureka's AP (availability over consistency) model means services remain discoverable even during network issues.
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for Eureka Server - Service Discovery.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this Java Master Course topic.
Search Terms
java-master-course, java master course, java, master, course, spring, framework, microservices
Related Java Master Course Topics