Eureka Sample
The Eureka sample demonstrates Spring Boot Admin Server integration with Netflix Eureka service discovery. This sample shows how to automatically discover and monitor Spring Boot applications registered with Eureka without using the Admin Client.
Overview
Location: spring-boot-admin-samples/spring-boot-admin-sample-eureka/
Features:
- Automatic service discovery via Eureka
- No Admin Client required on monitored applications
- Dynamic instance registration and deregistration
- Metadata-based configuration
- Docker Compose setup with multiple services
- Spring Security integration
- Health check integration with Eureka
Prerequisites
- Java 17 or higher
- Maven 3.6+
- Docker and Docker Compose (for full stack)
- Eureka Server running (or use Docker Compose)
Architecture
Key Points:
- Applications register with Eureka
- Admin Server discovers applications from Eureka
- No direct registration needed
Running the Sample
Option 1: With External Eureka Server
Start Eureka Server
# Using Docker
docker run -d -p 8761:8761 springcloud/eureka
# Or using Spring Cloud Eureka server JAR
java -jar eureka-server.jar
Verify Eureka is running: http://localhost:8761
Start Admin Server
cd spring-boot-admin-samples/spring-boot-admin-sample-eureka
mvn spring-boot:run
Access Admin UI at: http://localhost:8080
Option 2: Using Docker Compose (Recommended)
cd spring-boot-admin-samples/spring-boot-admin-sample-eureka
docker-compose up
This starts:
- Eureka Server (port 8761)
- Admin Server (port 8080)
- Spring Cloud Config Server (port 8888)
- Sample microservices (customers, stores)
- Supporting infrastructure (MongoDB, RabbitMQ)
Access Points:
- Admin UI:
http://localhost:8080 - Eureka UI:
http://localhost:8761 - Config Server:
http://localhost:8888 - Sample App UI:
http://localhost:80
Change Eureka URL
mvn spring-boot:run -Dspring-boot.run.arguments=\
--eureka.client.serviceUrl.defaultZone=http://other-eureka:8761/eureka/
Or set environment variable:
export EUREKA_SERVICE_URL=http://other-eureka:8761
mvn spring-boot:run
Project Structure
Dependencies
<dependencies>
<!-- Admin Server -->
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
<!-- Eureka Discovery Client -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- Security -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- Web (Servlet excluded, uses WebFlux) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webmvc</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
Note: Tomcat is excluded, so this sample runs on Netty (reactive stack).
Main Application Class
@Configuration
@EnableAutoConfiguration
@EnableDiscoveryClient // Enable Eureka discovery
@EnableAdminServer // Enable Admin Server
public class SpringBootAdminEurekaApplication {
private final AdminServerProperties adminServer;
public SpringBootAdminEurekaApplication(AdminServerProperties adminServer) {
this.adminServer = adminServer;
}
public static void main(String[] args) {
SpringApplication.run(SpringBootAdminEurekaApplication.class, args);
}
}
Key Annotations:
@EnableDiscoveryClient: Enables Eureka client functionality@EnableAdminServer: Enables Admin Server- Both work together to discover and monitor services
Configuration
Admin Server Configuration
spring:
application:
name: spring-boot-admin-sample-eureka
profiles:
active:
- secure
eureka:
instance:
leaseRenewalIntervalInSeconds: 10 # Heartbeat interval
health-check-url-path: /actuator/health
metadata-map:
startup: ${random.int} # Trigger refresh on restart
client:
registryFetchIntervalSeconds: 5 # Fetch registry every 5s
serviceUrl:
defaultZone: ${EUREKA_SERVICE_URL:http://localhost:8761}/eureka/
management:
endpoints:
web:
exposure:
include: "*" # Expose all actuator endpoints
endpoint:
health:
show-details: ALWAYS
Configuration Details:
- Lease Renewal: 10 seconds (faster detection of down instances)
- Registry Fetch: 5 seconds (quick discovery of new services)
- Health Check: Registered with Eureka
- Startup Metadata: Random value triggers endpoint update after restart
Client Application Configuration
For applications to be monitored, they only need:
spring:
application:
name: my-service # Service name in Eureka
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
metadata-map:
management.context-path: /actuator # Tell Admin where actuator is
management:
endpoints:
web:
exposure:
include: "*" # Expose endpoints
No Admin Client dependency needed!
Security Configuration
Insecure Profile
@Bean
@Profile("insecure")
public SecurityWebFilterChain securityWebFilterChainPermitAll(
ServerHttpSecurity http) {
return http
.authorizeExchange((authorizeExchange) ->
authorizeExchange.anyExchange().permitAll())
.csrf(ServerHttpSecurity.CsrfSpec::disable)
.build();
}
Secure Profile (Default)
@Bean
@Profile("secure")
public SecurityWebFilterChain securityWebFilterChainSecure(
ServerHttpSecurity http) {
return http
.authorizeExchange((authorizeExchange) ->
authorizeExchange
.pathMatchers(adminServer.path("/assets/**"))
.permitAll()
.pathMatchers("/actuator/health/**")
.permitAll()
.pathMatchers(adminServer.path("/login"))
.permitAll()
.anyExchange()
.authenticated())
.formLogin((formLogin) -> formLogin
.loginPage(adminServer.path("/login"))
.authenticationSuccessHandler(loginSuccessHandler(...)))
.logout((logout) -> logout
.logoutUrl(adminServer.path("/logout"))
.logoutSuccessHandler(logoutSuccessHandler(...)))
.httpBasic(Customizer.withDefaults())
.csrf(ServerHttpSecurity.CsrfSpec::disable)
.build();
}
Docker Compose Setup
Complete Stack
The docker-compose.yml provides a complete microservices environment:
version: '2'
services:
# Eureka Server
eureka:
image: springcloud/eureka
container_name: eureka
ports:
- "8761:8761"
environment:
- EUREKA_INSTANCE_PREFERIPADDRESS=true
# Admin Server
admin:
build:
context: .
dockerfile: ./src/main/docker/Dockerfile
depends_on:
- eureka
ports:
- "8080:8080"
environment:
- EUREKA_SERVICE_URL=http://eureka:8761
- EUREKA_INSTANCE_PREFER_IP_ADDRESS=true
# Spring Cloud Config Server
config:
image: springcloud/configserver
depends_on:
- eureka
ports:
- "8888:8888"
environment:
- EUREKA_SERVICE_URL=http://eureka:8761
# Sample Microservices
customers:
image: springcloud/customers
depends_on:
- config
- rabbit
environment:
- CONFIG_SERVER_URI=http://config:8888
- RABBITMQ_HOST=rabbit
stores:
image: springcloud/stores
depends_on:
- config
- rabbit
- mongodb
environment:
- CONFIG_SERVER_URI=http://config:8888
- RABBITMQ_HOST=rabbit
- MONGODB_HOST=mongodb
# Infrastructure
mongodb:
image: tutum/mongodb
ports:
- "27017:27017"
environment:
- AUTH=no
rabbit:
image: "rabbitmq:4"
ports:
- "5672:5672"
Start Stack
docker-compose up
Stop Stack
docker-compose down
View Logs
# All services
docker-compose logs -f
# Specific service
docker-compose logs -f admin
How It Works
Service Discovery Flow
-
Application Startup:
- Application starts and registers with Eureka
- Sends metadata including actuator path
- Eureka assigns instance ID
-
Admin Server Discovery:
- Admin Server fetches registry from Eureka every 5s
- Discovers new services
- Reads metadata to find actuator endpoints
-
Health Monitoring:
- Admin Server polls actuator endpoints
- Updates instance status
- Triggers notifications on status changes
-
Application Shutdown:
- Application deregisters from Eureka
- Admin Server removes instance from monitoring
Metadata Mapping
Admin Server reads specific metadata keys:
eureka:
instance:
metadata-map:
# Required for proper endpoint detection
management.context-path: /actuator
management.port: 8081 # If different from service port
# Optional - for authenticated actuators
user.name: admin
user.password: ${admin.password}
# Optional - custom metadata
startup: ${random.int} # Triggers refresh
environment: production
version: ${project.version}
Important Keys:
management.context-path: Where actuator endpoints are locatedmanagement.port: If management port differs from application portuser.name/user.password: Credentials for secured actuatorsstartup: Random value forces Admin to refresh endpoints after restart
Testing the Sample
Verify Eureka Registration
- Access Eureka UI:
http://localhost:8761 - Check "Instances currently registered with Eureka"
- Should see:
SPRING-BOOT-ADMIN-SAMPLE-EUREKA- Other registered services
Verify Admin Server Discovery
- Access Admin UI:
http://localhost:8080 - Should see all Eureka-registered services
- Click on each service to view:
- Health status
- Metrics
- Environment
- Logs
- JVM details
Test Dynamic Discovery
Register New Service
# Start another instance
SERVER_PORT=8081 mvn spring-boot:run
Within 5 seconds, it should appear in Admin UI.
Deregister Service
Stop the application (Ctrl+C). Within ~40 seconds (lease timeout), it should disappear from Admin UI.
Test Health Status Changes
Stop a monitored service and watch status change from UP → DOWN in Admin UI.
Advanced Configuration
Custom Service Filtering
Filter which services to monitor:
spring:
boot:
admin:
discovery:
ignored-services:
- eureka-server # Don't monitor Eureka itself
- config-server # Don't monitor Config Server
Service Grouping
Group services using metadata:
# Client application
eureka:
instance:
metadata-map:
group: backend-services
team: platform
Secure Actuator Endpoints
If client actuators are secured:
# Client application
eureka:
instance:
metadata-map:
user.name: actuator-admin
user.password: ${actuator.password}
Admin Server automatically uses these credentials.
Custom Health Check URL
eureka:
instance:
health-check-url-path: /custom/health
metadata-map:
management.context-path: /custom
Comparison: Eureka vs. Direct Registration
| Aspect | Eureka Discovery | Direct Registration |
|---|---|---|
| Setup | Eureka Server required | No additional infrastructure |
| Client Dependency | Only Eureka client | Admin Client required |
| Discovery | Automatic | Manual configuration |
| Scalability | Excellent (100+ services) | Limited (static config) |
| Dynamic Updates | Automatic | Manual restart |
| Use Case | Microservices | Monoliths, small deployments |
| Complexity | Higher | Lower |
Troubleshooting
Admin Server Not Discovering Services
Check Eureka connectivity:
# Test Eureka API
curl http://localhost:8761/eureka/apps
# Check Admin logs
docker-compose logs admin | grep -i eureka
Common Issues:
- Eureka URL incorrect
- Network connectivity issues
- Services not exposing actuator endpoints
Solution:
# Verify configuration
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/ # Trailing slash!
Services Show as DOWN
Check health endpoint:
curl http://localhost:8080/actuator/health
Verify metadata:
eureka:
instance:
metadata-map:
management.context-path: /actuator # Must match actual path
Slow Discovery
Services take too long to appear:
eureka:
client:
registryFetchIntervalSeconds: 5 # Reduce from default 30s
instance:
leaseRenewalIntervalInSeconds: 10 # Reduce from default 30s
Docker Compose Issues
Port conflicts:
# Change ports in docker-compose.yml
ports:
- "9090:8080" # Map to different host port
Container connectivity:
# Check network
docker network inspect spring-boot-admin-sample-eureka_discovery
# Check container logs
docker-compose logs eureka
Production Considerations
High Availability
Run multiple Eureka servers:
eureka:
client:
serviceUrl:
defaultZone: http://eureka1:8761/eureka/,http://eureka2:8761/eureka/
Security
Secure Eureka communication:
eureka:
client:
serviceUrl:
defaultZone: https://${eureka.user}:${eureka.password}@eureka:8761/eureka/
Performance Tuning
Optimize for large deployments:
spring:
boot:
admin:
monitor:
period: 20000 # Increase polling interval (ms)
connect-timeout: 5000
read-timeout: 10000
eureka:
client:
registryFetchIntervalSeconds: 10 # Balance freshness vs. load
Monitoring Eureka Itself
Register Admin Server with itself:
spring:
boot:
admin:
discovery:
ignored-services: [] # Don't ignore any services
Key Takeaways
This sample demonstrates:
✅ Service Discovery Integration
- Automatic discovery via Eureka
- No Admin Client dependency needed
✅ Dynamic Monitoring
- Services auto-register/deregister
- Real-time discovery updates
✅ Complete Setup
- Complete microservices stack
- Docker Compose orchestration
✅ Scalable Architecture
- Handles many services efficiently
- Centralized monitoring
Next Steps
- Explore Consul Sample for alternative service discovery
- Review Zookeeper Sample for Apache Zookeeper
- Check Integration Guide for detailed Eureka setup
- See Hazelcast Sample for clustering