Volver a Spring Boot Intermedio
Spring Boot
Spring Boot Intermedio
Microservicios con Spring Boot
Los microservicios descomponen un monolito en servicios independientes y desplegables que se comunican por red.
¿Por qué Microservicios?
- Despliegue independiente — actualiza un servicio sin tocar los demás
- Diversidad tecnológica — cada servicio puede usar un stack diferente
- Escalabilidad — escala solo los servicios bajo carga
- Aislamiento de fallos — los errores no se propagan al sistema completo
Resumen de Spring Cloud
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
Descubrimiento de Servicios con Eureka
// Servidor Eureka
@SpringBootApplication
@EnableEurekaServer
public class ServidorDescubrimiento {
public static void main(String[] args) {
SpringApplication.run(ServidorDescubrimiento.class, args);
}
}
# application.yml del servidor Eureka
server:
port: 8761
eureka:
client:
register-with-eureka: false
fetch-registry: false
# application.yml del servicio cliente
spring:
application:
name: servicio-productos
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
API Gateway
spring:
cloud:
gateway:
routes:
- id: servicio-productos
uri: lb://servicio-productos
predicates:
- Path=/api/productos/**
filters:
- StripPrefix=1
- id: servicio-pedidos
uri: lb://servicio-pedidos
predicates:
- Path=/api/pedidos/**
Comunicación entre Servicios con OpenFeign
// Declaración del cliente Feign
@FeignClient(name = "servicio-productos", fallback = ProductoClienteFallback.class)
public interface ProductoCliente {
@GetMapping("/api/productos/{id}")
ProductoResponse obtenerProducto(@PathVariable Long id);
@PutMapping("/api/productos/{id}/stock")
void actualizarStock(@PathVariable Long id, @RequestBody ActualizarStockRequest req);
}
// Uso en el servicio de pedidos
@Service
public class ServicioPedidos {
private final ProductoCliente productoCliente;
public Pedido crearPedido(CrearPedidoRequest request) {
ProductoResponse producto = productoCliente.obtenerProducto(request.getProductoId());
// ... crear pedido
}
}
Circuit Breaker con Resilience4j
// Implementación de fallback
@Component
public class ProductoClienteFallback implements ProductoCliente {
@Override
public ProductoResponse obtenerProducto(Long id) {
return new ProductoResponse(id, "Producto Desconocido", BigDecimal.ZERO);
}
@Override
public void actualizarStock(Long id, ActualizarStockRequest req) {
// registrar fallo, reintentar después por cola de mensajes
}
}
// Circuit breaker programático
@Service
public class ServicioProductos {
private final CircuitBreakerFactory cbFactory;
public ProductoResponse obtenerProducto(Long id) {
CircuitBreaker cb = cbFactory.create("servicio-productos");
return cb.run(
() -> productoCliente.obtenerProducto(id),
throwable -> new ProductoResponse(id, "No disponible", BigDecimal.ZERO)
);
}
}
resilience4j:
circuitbreaker:
instances:
servicio-productos:
sliding-window-size: 10
failure-rate-threshold: 50
wait-duration-in-open-state: 10s
Trazado Distribuido con Micrometer
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-brave</artifactId>
</dependency>
<dependency>
<groupId>io.zipkin.reporter2</groupId>
<artifactId>zipkin-reporter-brave</artifactId>
</dependency>
management:
tracing:
sampling:
probability: 1.0
zipkin:
tracing:
endpoint: http://localhost:9411/api/v2/spans
Docker Compose para Desarrollo Local
version: '3.8'
services:
eureka:
image: steeltoeoss/eureka-server
ports:
- "8761:8761"
postgres:
image: postgres:15
environment:
POSTGRES_PASSWORD: secreto
ports:
- "5432:5432"
zipkin:
image: openzipkin/zipkin
ports:
- "9411:9411"
servicio-productos:
build: ./servicio-productos
environment:
SPRING_PROFILES_ACTIVE: docker
EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://eureka:8761/eureka/
depends_on:
- eureka
- postgres