Servidor de descubrimiento de servicios (Service Discovery) basado en Netflix Eureka. Actúa como registro centralizado para todos los microservicios de la arquitectura BusConnect, permitiendo el descubrimiento dinámico de servicios y balanceo de carga del lado del cliente.
Eureka Server es el corazón del Service Discovery en la arquitectura de microservicios:
- Registro de Servicios: Los microservicios se registran automáticamente al iniciar
- Health Checks: Monitoreo continuo de la salud de los servicios
- Service Discovery: Los clientes consultan Eureka para localizar servicios
- Load Balancing: Distribuye peticiones entre instancias disponibles
- Self-Preservation: Protección contra fallos de red masivos
- Spring Boot: 3.3.13
- Spring Cloud Netflix Eureka Server: Service Discovery
- Spring Boot Actuator: Health checks y métricas
- Spring Web: UI de gestión de Eureka
- Puerto del servidor:
8761 - UI de Eureka:
http://localhost:8761 - API de Eureka:
http://localhost:8761/eureka/
eureka:
client:
register-with-eureka: false # No se registra a sí mismo
fetch-registry: false # No necesita obtener el registro
server:
enable-self-preservation: false # Deshabilitado en desarrollo
eviction-interval-timer-in-ms: 5000 # Verificación cada 5sDeshabilitado en desarrollo para detectar fallos rápidamente.
En producción debería estar habilitado:
eureka:
server:
enable-self-preservation: trueAbrir en el navegador: http://localhost:8761
- Registered Instances: Lista de servicios registrados
- General Info: Estado del servidor
- System Status: Información del entorno
- DS Replicas: Réplicas del servidor (si hay cluster)
- Instances Currently Registered: Instancias activas por servicio
Application AMIs Availability Zones Status
API-GATEWAY n/a (1) (1) UP (1) - api-gateway:8080
CATALOG-SERVICE n/a (1) (1) UP (1) - catalog-service:8083
USER-SERVICE n/a (1) (1) UP (1) - user-service:8082
Obtiene todos los servicios registrados (formato XML por defecto).
curl http://localhost:8761/eureka/appsObtiene información de un servicio específico.
curl http://localhost:8761/eureka/apps/CATALOG-SERVICEObtiene información de una instancia específica.
curl http://localhost:8761/eureka/apps/CATALOG-SERVICE/catalog-service:8083Health check del servidor Eureka.
curl http://localhost:8761/actuator/healthResponse:
{
"status": "UP",
"components": {
"diskSpace": {
"status": "UP"
},
"ping": {
"status": "UP"
}
}
}Información general del servicio.
curl http://localhost:8761/actuator/infoLos microservicios deben incluir esta configuración para registrarse en Eureka:
spring:
application:
name: mi-servicio
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
register-with-eureka: true
fetch-registry: true
instance:
prefer-ip-address: true
instance-id: ${spring.application.name}:${random.value}<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>@SpringBootApplication
@EnableDiscoveryClient
public class MiServicioApplication {
// ...
}El servicio incluye un Dockerfile multi-stage optimizado con:
- ✅ Build multi-stage
- ✅ Usuario no-root (spring:spring)
- ✅ Health check integrado
- ✅ JVM optimizado (512MB max heap)
- ✅ Base Alpine (imagen ligera)
docker build -t busconnect/eureka-service:latest .docker run -d \
-p 8761:8761 \
--name eureka-service \
busconnect/eureka-service:latestEl contenedor incluye health check automático:
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:8761/actuator/health || exit 1Requisitos previos:
- Java 21
- Maven 3.9+
Pasos:
# Opción 1: Maven
mvn spring-boot:run
# Opción 2: JAR
mvn clean package
java -jar target/eureka-server-0.0.1-SNAPSHOT.jardocker-compose up eureka-serviceeureka-service/
├── src/
│ └── main/
│ ├── java/
│ │ └── com/busconnect/eurekaservice/
│ │ ├── EurekaServiceApplication.java
│ │ └── service/
│ │ ├── EurekaServiceI.java
│ │ └── EurekaService.java
│ └── resources/
│ └── application.yml
├── docker-compose.yml
├── Dockerfile
├── pom.xml
└── README.md
| Servicio | Puerto | Descripción |
|---|---|---|
| api-gateway | 8080 | API Gateway - Punto de entrada único |
| catalog-service | 8083 | Gestión de rutas y catálogo |
| user-service | 8082 | Gestión de usuarios |
# Ver todos los servicios
curl http://localhost:8761/eureka/apps | grep "<app>"
# Ver instancias de catalog-service
curl -H "Accept: application/json" \
http://localhost:8761/eureka/apps/CATALOG-SERVICEPara producción, se recomienda un cluster de servidores Eureka:
Servidor 1:
eureka:
client:
service-url:
defaultZone: http://eureka2:8761/eureka/,http://eureka3:8761/eureka/
instance:
hostname: eureka1Servidor 2:
eureka:
client:
service-url:
defaultZone: http://eureka1:8761/eureka/,http://eureka3:8761/eureka/
instance:
hostname: eureka2eureka:
server:
response-cache-update-interval-ms: 5000 # Actualización de caché
eviction-interval-timer-in-ms: 5000 # Intervalo de evicción
instance:
lease-renewal-interval-in-seconds: 10 # Renovación de lease
lease-expiration-duration-in-seconds: 30 # Expiración de leaseeureka:
instance:
lease-renewal-interval-in-seconds: 30 # Heartbeat cada 30s
lease-expiration-duration-in-seconds: 90 # Expira después de 90s sin heartbeat- ✅ Usuario no-root en Docker
- ✅ Health checks habilitados
- ✅ Self-preservation configurable
- ✅ Actuator endpoints limitados
- Autenticación básica HTTP
- HTTPS/TLS
- Autenticación de servicios con tokens
- Rate limiting
- Monitoreo con Spring Boot Admin
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>spring:
security:
user:
name: admin
password: ${EUREKA_PASSWORD}curl http://localhost:8761/actuator/healthcurl -H "Accept: application/json" \
http://localhost:8761/eureka/appscurl -X POST \
http://localhost:8761/eureka/apps/TEST-SERVICE \
-H "Content-Type: application/json" \
-d '{
"instance": {
"hostName": "localhost",
"app": "TEST-SERVICE",
"ipAddr": "127.0.0.1",
"port": {"$": 9999, "@enabled": true},
"status": "UP",
"dataCenterInfo": {
"@class": "com.netflix.appinfo.InstanceInfo$DefaultDataCenterInfo",
"name": "MyOwn"
}
}
}'curl -X DELETE \
http://localhost:8761/eureka/apps/TEST-SERVICE/localhost:TEST-SERVICE:9999# Ver logs en Docker
docker logs -f eureka-service
# Ver logs con fecha
docker logs --since 30m eureka-service- Registered Replicas: Número de réplicas registradas
- Current Time: Hora actual del servidor
- Uptime: Tiempo de actividad
- Renewal Threshold: Umbral de renovaciones por minuto
- Renews (last min): Renovaciones en el último minuto
Visible en el dashboard web:
EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT.
RENEWALS ARE LESSER THAN THRESHOLD AND HENCE THE INSTANCES ARE NOT BEING EXPIRED JUST TO BE SAFE.
Posibles causas:
- URL de Eureka incorrecta en el cliente
- Cliente no tiene
@EnableDiscoveryClient - Cliente no puede alcanzar Eureka (red/firewall)
- Self-preservation activo (no expira servicios)
Solución:
# Verificar logs del cliente
docker logs mi-servicio
# Verificar conectividad
curl http://localhost:8761/actuator/health
# Verificar configuración del cliente
cat config/application.ymlCausas:
- Health check del servicio falla
- Servicio no responde a heartbeats
Solución:
# Verificar health del servicio
curl http://localhost:8083/actuator/health
# Revisar logs
docker logs catalog-serviceCausa: instance-id no es único
Solución:
eureka:
instance:
instance-id: ${spring.application.name}:${random.value}Mensaje: "EMERGENCY! EUREKA MAY BE INCORRECTLY..."
Causa: Muchos servicios dejaron de enviar heartbeats
Solución:
- En desarrollo: Desactivar self-preservation
- En producción: Investigar problemas de red
eureka:
server:
eviction-interval-timer-in-ms: 1000 # Verificar cada 1s
instance:
lease-renewal-interval-in-seconds: 5 # Heartbeat cada 5s
lease-expiration-duration-in-seconds: 10 # Expirar después de 10s# Configuración de memoria
JAVA_OPTS="-Xms256m -Xmx512m -XX:+UseG1GC"
# En Docker
docker run -e JAVA_OPTS="-Xms256m -Xmx512m" eureka-serviceEl API Gateway usa Eureka para descubrir servicios:
spring:
cloud:
gateway:
routes:
- id: catalog-service
uri: lb://CATALOG-SERVICE # lb = load balanced via EurekaLos microservicios se registran automáticamente:
@SpringBootApplication
@EnableDiscoveryClient
public class CatalogServiceApplication {
// Se registra automáticamente en Eureka
}@LoadBalanced
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
// Usar nombre del servicio en lugar de URL
restTemplate.getForObject("http://CATALOG-SERVICE/api/routes", Routes.class);@LoadBalanced
@Bean
public WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
// Llamada reactiva
webClient.get()
.uri("http://USER-SERVICE/api/users/{id}", userId)
.retrieve()
.bodyToMono(User.class);Este proyecto es parte del sistema BusConnect.
Para más información sobre la arquitectura general del proyecto, consultar el README principal.