Microservicios

Cómo descomponer un sistema en servicios pequeños, autónomos y desplegables de forma independiente, alineados con dominios de negocio.

Qué problema resuelve

A medida que una aplicación monolítica crece, surgen problemas que frenan al equipo:

  • Despliegues arriesgados: Un cambio pequeño requiere redesplegar toda la aplicación
  • Escalado ineficiente: Para escalar una funcionalidad, debes escalar todo el monolito
  • Equipos bloqueados: Múltiples equipos trabajan en el mismo código base y se bloquean mutuamente
  • Tecnología homogénea: Todo el sistema debe usar el mismo lenguaje, framework y base de datos
  • Tiempo de build creciente: Compilar y testear todo el monolito toma cada vez más tiempo
Monolito:
┌─────────────────────────────────┐
│         Aplicación              │
│  ┌─────┐ ┌─────┐ ┌──────────┐  │
│  │Users│ │Prods│ │  Orders   │  │
│  └─────┘ └─────┘ └──────────┘  │
│  ┌─────────────────────────────┐│
│  │     Base de datos única     ││
│  └─────────────────────────────┘│
└─────────────────────────────────┘
  Un deploy = todo el sistema
  Un fallo = todo el sistema

Cómo funciona

La arquitectura de microservicios descompone el sistema en servicios pequeños e independientes, cada uno responsable de una capacidad de negocio específica. Cada servicio:

  • Tiene su propia base de datos (Database per Service)
  • Se despliega de forma independiente
  • Se comunica con otros servicios a través de APIs o eventos
  • Es propiedad de un equipo específico
Microservicios:
┌──────────┐  ┌──────────┐  ┌──────────┐
│  Users   │  │ Products │  │  Orders  │
│ Service  │  │ Service  │  │ Service  │
│  ┌────┐  │  │  ┌────┐  │  │  ┌────┐  │
│  │ DB │  │  │  │ DB │  │  │  │ DB │  │
│  └────┘  │  │  └────┘  │  │  └────┘  │
└──────────┘  └──────────┘  └──────────┘
     │              │              │
     └──────── Event Bus ─────────┘

Principios de descomposición

La clave está en cómo dividir el sistema. Los criterios más efectivos son:

CriterioDescripciónEjemplo
Por dominio de negocioCada servicio representa un bounded context de DDDUser Service, Order Service, Payment Service
Por capacidad de negocioCada servicio implementa una capacidad organizacionalFacturación, Inventario, Notificaciones
Por subdomainAlineado con subdominios del negocioCore (pedidos), Supporting (reportes), Generic (auth)

Comunicación entre servicios

Los microservicios se comunican de dos formas principales:

Síncrona (request-response):

Order Service ──HTTP/gRPC──► Product Service
                              "¿Hay stock del producto X?"
                              ← "Sí, 50 unidades"

Asíncrona (eventos):

Order Service ──evento──► Event Bus ──► Inventory Service
                "OrderCreated"          "Reservar stock"
                                  ──► Notification Service
                                        "Enviar email"

Database per Service

Cada microservicio es dueño de sus datos. Ningún otro servicio accede directamente a su base de datos:

✅ Correcto:
  Order Service ──API──► User Service
                         "Dame el nombre del usuario 123"

❌ Incorrecto:
  Order Service ──SQL──► User DB
                         "SELECT name FROM users WHERE id=123"

Esto garantiza encapsulamiento y permite que cada servicio elija la tecnología de almacenamiento más adecuada (SQL, NoSQL, cache, etc.).

Ventajas

  • Despliegue independiente: Cada servicio se despliega sin afectar a los demás
  • Escalado granular: Escala solo los servicios que lo necesitan
  • Autonomía de equipos: Cada equipo es dueño de su servicio end-to-end
  • Diversidad tecnológica: Cada servicio puede usar el lenguaje y framework más adecuado
  • Resiliencia: Un fallo en un servicio no necesariamente tumba todo el sistema
  • Time to market: Equipos pequeños pueden entregar más rápido

Trade-offs / Desventajas

  • Complejidad distribuida: Debugging, testing y tracing son significativamente más difíciles
  • Consistencia eventual: Las transacciones distribuidas son complejas (requieren Sagas, Outbox)
  • Latencia de red: La comunicación entre servicios añade latencia
  • Overhead operativo: Más servicios = más despliegues, más monitoreo, más infraestructura
  • Duplicación de datos: Cada servicio puede necesitar copias de datos de otros servicios
  • Complejidad organizacional: Requiere equipos maduros con cultura DevOps

Cuándo usar

  • Sistemas grandes con múltiples equipos de desarrollo
  • Cuando diferentes partes del sistema tienen requisitos de escalado muy distintos
  • Cuando necesitas desplegar funcionalidades de forma independiente y frecuente
  • Organizaciones con equipos autónomos alineados con dominios de negocio
  • Sistemas donde la resiliencia y la disponibilidad son críticas

Cuándo evitar

  • Equipos pequeños (menos de 8-10 desarrolladores) donde el overhead no se justifica
  • Sistemas con dominio simple que no requiere descomposición
  • Cuando no tienes infraestructura de CI/CD, monitoreo y orquestación madura
  • Prototipos o MVPs donde la velocidad de desarrollo es prioridad
  • Cuando no puedes definir bounded contexts claros (señal de que el dominio no está bien entendido)

Tecnologías e implementaciones comunes

CategoríaOpciones
Comunicación síncronaREST, gRPC, GraphQL
Comunicación asíncronaKafka, RabbitMQ, Amazon SQS, NATS
OrquestaciónKubernetes, Docker Swarm, Amazon ECS
Service DiscoveryConsul, Eureka, DNS-based (Kubernetes)
ObservabilidadJaeger, Zipkin, OpenTelemetry, Prometheus
API GatewayKong, Traefik, AWS API Gateway

Relación con otros patrones

  • DDD (Domain-Driven Design): Proporciona los criterios para definir los límites de cada servicio
  • API Gateway: Punto de entrada único para los clientes externos
  • Saga Pattern: Maneja transacciones que cruzan múltiples servicios
  • Event-Driven Architecture: Patrón de comunicación asíncrona entre servicios
  • Circuit Breaker: Protege los servicios de fallos en cascada

Próximos pasos

Los microservicios son un estilo arquitectónico poderoso pero exigente. Para entender cómo manejar la comunicación asíncrona entre ellos, explora Event-Driven Architecture. Para proteger la comunicación con sistemas externos, revisa el Anti-Corruption Layer.