La arquitectura de microservicios consiste en construir una aplicación como un conjunto de servicios pequeños, autónomos y desplegables de forma independiente, cada uno responsable de una capacidad de negocio concreta y comunicándose mediante mecanismos ligeros como APIs HTTP o mensajería. Es uno de los estilos arquitectónicos más populares de la última década, pero también uno de los más malinterpretados: aporta enormes beneficios cuando se aplica con criterio y un coste de complejidad considerable cuando se adopta por moda.

En esta lección definiremos sus características, lo compararemos con el monolito, analizaremos cuándo conviene (y cuándo no) y veremos un ejemplo concreto de descomposición de una aplicación de seguros.

Contenido

  1. Definición y características
  2. Microservicios frente a monolito
  3. El monolito modular como alternativa
  4. Cuándo SÍ usar microservicios
  5. Cuándo NO usar microservicios
  6. Ejemplo de descomposición
  7. Errores comunes y consejos
  8. Ejercicios
  9. Conclusión

  1. Definición y características

Un microservicio es un servicio que cumple, idealmente, estas características:

  • Responsabilidad única de negocio: gestiona una capacidad concreta (pólizas, siniestros, facturación).
  • Despliegue independiente: se puede desplegar sin coordinar con el resto.
  • Base de datos propia: cada servicio es dueño de sus datos; nadie accede a su base de datos directamente.
  • Autonomía de equipo: un equipo lo desarrolla, prueba y opera de principio a fin.
  • Comunicación por red: vía API o mensajes, nunca compartiendo memoria.
  • Tolerancia a fallos: diseñado para soportar que sus dependencias fallen.
graph TB
    subgraph "Aplicación de Seguros"
        P[Servicio Pólizas]
        S[Servicio Siniestros]
        C[Servicio Clientes]
        F[Servicio Facturación]
    end
    P --> DBP[(BD Pólizas)]
    S --> DBS[(BD Siniestros)]
    C --> DBC[(BD Clientes)]
    F --> DBF[(BD Facturación)]

Fíjate en que cada servicio tiene su propia base de datos. Este es uno de los principios más importantes: un servicio nunca lee ni escribe en la base de datos de otro. Si necesita datos ajenos, los pide por API o reacciona a eventos.

  1. Microservicios frente a monolito

Un monolito es una aplicación desplegada como una única unidad. No es intrínsecamente malo; de hecho, suele ser el punto de partida correcto. La comparación honesta es:

Aspecto Monolito Microservicios
Despliegue Una unidad Muchas unidades independientes
Escalado Todo o nada Por servicio, según necesidad
Complejidad operativa Baja Alta (red, observabilidad, orquestación)
Velocidad inicial Alta Baja (mucha infraestructura previa)
Aislamiento de fallos Pobre (un fallo puede tumbar todo) Bueno (fallos contenidos)
Transacciones ACID locales sencillas Distribuidas y complejas (sagas)
Tecnología Una pila común Heterogénea por servicio
Autonomía de equipos Baja (todos tocan lo mismo) Alta
Depuración Sencilla (un proceso, una traza) Compleja (trazas distribuidas)

La conclusión clave: los microservicios cambian complejidad de desarrollo por complejidad operativa. No la eliminan.

  1. El monolito modular como alternativa

Antes de saltar a microservicios, existe una opción intermedia muy infravalorada: el monolito modular. Se trata de un único desplegable, pero internamente organizado en módulos con fronteras claras y comunicación explícita entre ellos.

// Módulos bien separados dentro de un único desplegable.
// El módulo de siniestros NO accede a las clases internas de pólizas;
// solo usa su API pública (una interfaz).
package com.fiatc.siniestros;

public class ServicioSiniestros {

    private final PolizaApi polizaApi; // interfaz pública del módulo Pólizas

    public ServicioSiniestros(PolizaApi polizaApi) {
        this.polizaApi = polizaApi;
    }

    public void registrarSiniestro(String polizaId) {
        // Consultamos a través de la API pública, no de tablas internas
        if (!polizaApi.estaVigente(polizaId)) {
            throw new IllegalStateException("La póliza no está vigente");
        }
        // ... lógica de registro
    }
}

Este enfoque te da fronteras limpias sin el coste de la red. Si más adelante un módulo necesita escalar o desplegarse por separado, ya está aislado y extraerlo a un microservicio es mucho más fácil. Es la estrategia recomendada para empezar.

  1. Cuándo SÍ usar microservicios

Los microservicios tienen sentido cuando se cumplen varias de estas condiciones:

  • La organización es grande: muchos equipos que se pisan al trabajar sobre el mismo código.
  • Necesidades de escalado dispares: el servicio de facturación necesita 20 instancias y el de configuración solo 1.
  • Ritmos de cambio distintos: unas partes cambian a diario y otras casi nunca.
  • Requisitos de disponibilidad por dominio: aislar un fallo en siniestros para que no tumbe la contratación.
  • Madurez en DevOps: existe automatización de CI/CD, contenedores, observabilidad y orquestación.

La famosa "ley de Conway" lo resume: la arquitectura del sistema tiende a reflejar la estructura de comunicación de la organización. Si tienes equipos autónomos, los microservicios encajan.

  1. Cuándo NO usar microservicios

Evita los microservicios si:

  • El equipo es pequeño: la sobrecarga operativa no compensa.
  • El dominio no está claro: si aún no entiendes bien las fronteras, las dibujarás mal y pagarás un coste altísimo por corregirlas.
  • No hay madurez operativa: sin observabilidad ni automatización, depurar es un infierno.
  • Buscas rendimiento extremo en transacciones: las transacciones distribuidas son lentas y complejas.

Un antipatrón habitual es el monolito distribuido: microservicios tan acoplados entre sí que hay que desplegarlos juntos. Reúne lo peor de ambos mundos: la complejidad de la red y la rigidez del monolito.

Síntoma Diagnóstico
Para desplegar un servicio hay que desplegar otros Monolito distribuido
Un cambio de esquema afecta a varios servicios Fronteras mal definidas
Servicios que comparten base de datos Acoplamiento de datos
Cadenas largas de llamadas síncronas Acoplamiento temporal

  1. Ejemplo de descomposición

Partamos de un monolito de seguros con todo en un solo proceso: clientes, pólizas, siniestros y facturación. Una descomposición razonable, por capacidades de negocio, sería:

# Mapa de servicios resultante
servicios:
  - nombre: clientes
    responsabilidad: "Datos de contacto y perfil del asegurado"
    datos_propios: [cliente, direccion]
  - nombre: polizas
    responsabilidad: "Contratación y ciclo de vida de pólizas"
    datos_propios: [poliza, cobertura]
  - nombre: siniestros
    responsabilidad: "Apertura y tramitación de siniestros"
    datos_propios: [siniestro, peritaje]
  - nombre: facturacion
    responsabilidad: "Recibos, cobros y devoluciones"
    datos_propios: [recibo, cobro]

Cada servicio es dueño de sus tablas. ¿Cómo obtiene el servicio de siniestros el nombre del cliente? No accede a la base de datos de clientes; lo pide por API o mantiene una copia local de los pocos datos que necesita, actualizada mediante eventos:

sequenceDiagram
    participant CL as Servicio Clientes
    participant BUS as Bus de eventos
    participant SI as Servicio Siniestros
    CL->>BUS: Evento ClienteActualizado
    BUS->>SI: ClienteActualizado
    Note over SI: Actualiza su copia local<br/>(nombre, NIF anonimizado)

Cuando un cliente cambia sus datos, el servicio de clientes publica un evento. El de siniestros mantiene una copia mínima de lo que necesita y la actualiza al recibirlo. Así se evita el acoplamiento directo a la base de datos ajena.

Errores Comunes y Consejos

  • Empezar directamente con microservicios: prefiere un monolito modular hasta entender bien el dominio.
  • Compartir base de datos entre servicios: rompe la autonomía y crea acoplamiento oculto. Cada servicio, su base de datos.
  • Hacer microservicios demasiado pequeños (nanoservicios): generan una explosión de llamadas de red y dificultan razonar sobre el sistema.
  • Olvidar la observabilidad: invierte desde el día uno en trazas distribuidas, métricas y logs correlacionados.
  • Sincronizar todo: las cadenas largas de llamadas síncronas acoplan disponibilidad. Considera eventos asíncronos.

Ejercicios

  1. Construye una tabla con tres ventajas y tres inconvenientes de los microservicios frente al monolito, justificando cada punto.
  2. Una startup de 4 desarrolladores quiere lanzar un MVP en 3 meses. ¿Recomendarías microservicios? Razona tu respuesta y propón una alternativa.
  3. Dado un monolito de e-commerce con módulos de catálogo, carrito, pedidos y pagos, propón una descomposición en servicios indicando qué datos posee cada uno y cómo obtiene el servicio de pedidos el precio actual de un producto.

Soluciones

  1. Ventajas: despliegue independiente (menos coordinación), escalado selectivo (ahorro de recursos), aislamiento de fallos (mayor disponibilidad). Inconvenientes: complejidad operativa (red, orquestación), transacciones distribuidas (sagas), depuración más difícil (trazas distribuidas).

  2. No. Con 4 personas y prisa por validar el producto, la sobrecarga operativa de los microservicios retrasaría el MVP. Recomendación: un monolito modular con fronteras limpias, que permita extraer servicios más adelante si el producto crece.

  3. Catálogo posee producto y precio; carrito posee linea_carrito; pedidos posee pedido y linea_pedido; pagos posee transaccion. El servicio de pedidos obtiene el precio llamando a la API del catálogo en el momento de confirmar el pedido y, muy importante, guarda el precio aplicado en su propia tabla linea_pedido, porque el precio del catálogo puede cambiar después.

Conclusión

Los microservicios son servicios pequeños, autónomos y desplegables de forma independiente, cada uno dueño de sus datos. Cambian complejidad de desarrollo por complejidad operativa, así que solo merecen la pena cuando la organización, el escalado y la madurez técnica lo justifican. En caso de duda, el monolito modular es un excelente punto de partida.

La pregunta más difícil que queda pendiente es dónde trazar las fronteras entre servicios. A ello dedicaremos la siguiente lección, Descomposición de Servicios y Bounded Contexts, donde aplicaremos las ideas del Diseño Guiado por el Dominio para acertar con el tamaño y los límites de cada servicio.

Curso de Arquitectura de Aplicaciones

Módulo 1: Fundamentos de la Arquitectura de Aplicaciones

Módulo 2: Principios y Tácticas de Diseño

Módulo 3: Estilos y Patrones Arquitectónicos

Módulo 4: Arquitecturas Distribuidas y Microservicios

Módulo 5: Arquitecturas Dirigidas por Eventos y Mensajería

Módulo 6: Diseño Dirigido por el Dominio (DDD)

Módulo 7: Datos y Persistencia

Módulo 8: Arquitectura en la Nube y Despliegue

Módulo 9: Calidad, Seguridad y Observabilidad

Módulo 10: Evolución, Gobernanza y Casos Prácticos

© Copyright 2026. Todos los derechos reservados