Los microservicios son un estilo de arquitectura de software en el que una aplicación se construye como un conjunto de servicios pequeños, independientes y desplegables de forma autónoma, cada uno ejecutándose en su propio proceso y comunicándose mediante mecanismos ligeros (normalmente APIs HTTP/REST o mensajería asíncrona).
Cada microservicio está orientado a una capacidad de negocio concreta y puede ser desarrollado, desplegado y escalado de forma independiente al resto del sistema.
Este enfoque contrasta con la arquitectura monolítica tradicional, en la que toda la lógica de la aplicación reside en un único bloque de código desplegado como una sola unidad.
Cada servicio es independiente de los demás. Los cambios en un servicio no obligan a modificar ni redesplegar otros servicios. La comunicación entre servicios se realiza a través de interfaces bien definidas (APIs), ocultando los detalles de implementación internos.
El bajo acoplamiento es una característica fundamental. Su opuesto, el acoplamiento fuerte, es precisamente lo que los microservicios buscan evitar.
Cada microservicio agrupa toda la lógica relacionada con una única responsabilidad de negocio. Siguiendo el Principio de Responsabilidad Única, un servicio hace una sola cosa y la hace bien.
Los microservicios son autónomos: pueden ser desarrollados, probados, desplegados y escalados de manera totalmente independiente. Cada equipo puede trabajar en su servicio sin coordinación constante con otros equipos.
Al estar desacoplados, los microservicios permiten una escalabilidad granular: solo se escalan los servicios que lo necesitan (por ejemplo, el servicio de pagos en un pico de ventas), sin necesidad de escalar toda la aplicación.
Los sistemas de microservicios se diseñan asumiendo que los fallos ocurrirán. Patrones como el Circuit Breaker, los reintentos con backoff exponencial y los timeouts permiten que el sistema continúe funcionando aunque uno o varios servicios fallen, degradando la funcionalidad de forma controlada en lugar de colapsar por completo.
Cada servicio tiene su propio ciclo de vida de despliegue. Esto habilita prácticas de entrega continua (CD) y permite publicar nuevas versiones de un servicio sin afectar al resto del sistema.
Los microservicios se definen según dominios funcionales del negocio (p. ej., usuarios, pedidos, inventario, notificaciones), no según capas técnicas horizontales.
Los microservicios necesitan comunicarse entre sí. Existen dos grandes modelos:
Un componente centralizado que actúa como punto de entrada único para todos los clientes. Se encarga del enrutamiento, autenticación, limitación de tasa (rate limiting), transformación de respuestas y agregación de resultados.
Cuando un servicio detecta que otro está fallando repetidamente, "abre el circuito" y deja de enviarle peticiones durante un tiempo, evitando la propagación del fallo en cascada.
En entornos dinámicos (contenedores, cloud), las instancias de servicios aparecen y desaparecen. El Service Discovery permite que los servicios se localicen dinámicamente sin configuración estática de IPs. Ejemplos: Consul, Eureka, Kubernetes DNS.
Un proceso auxiliar se despliega junto al servicio principal para gestionar funcionalidades transversales: observabilidad, seguridad (mTLS), proxying. Es la base del patrón Service Mesh (Istio, Linkerd).
Patrón para gestionar transacciones distribuidas que abarcan múltiples servicios. En lugar de una transacción ACID tradicional, una Saga coordina una secuencia de transacciones locales con operaciones de compensación en caso de fallo.
Separa las operaciones de escritura (comandos) de las de lectura (consultas) en modelos de datos distintos, optimizando cada uno para su caso de uso.
En lugar de almacenar únicamente el estado actual, se almacena la secuencia completa de eventos que llevaron a ese estado. Permite reconstruir el estado en cualquier punto del tiempo y facilita la auditoría.
| Ventaja | Descripción |
|---|---|
| Despliegue independiente | Ciclos de entrega más rápidos por servicio |
| Escalabilidad granular | Solo se escala lo que se necesita |
| Resiliencia | Un fallo aislado no derrumba todo el sistema |
| Flexibilidad tecnológica | Cada servicio puede usar el lenguaje o base de datos más apropiado |
| Equipos autónomos | Organización más ágil siguiendo la Ley de Conway |
| Mantenibilidad | Bases de código más pequeñas y comprensibles |
| Reto | Descripción |
|---|---|
| Complejidad operacional | Gestionar decenas o cientos de servicios requiere madurez en DevOps |
| Latencia de red | La comunicación entre servicios introduce latencia que en un monolito sería una llamada local |
| Consistencia de datos | Sin transacciones ACID globales, mantener la consistencia es más complejo |
| Depuración distribuida | Rastrear errores a través de múltiples servicios requiere herramientas de observabilidad (distributed tracing) |
| Sobrecarga inicial | Configurar la infraestructura (CI/CD, contenedores, orquestación) tiene un coste elevado |
| Aspecto | Monolito | Microservicios |
|---|---|---|
| Acoplamiento | Alto (fuerte) | Bajo (débil) |
| Despliegue | Todo o nada | Por servicio individual |
| Escalado | Toda la aplicación | Por servicio |
| Tecnología | Única pila tecnológica | Heterogénea |
| Complejidad inicial | Baja | Alta |
| Complejidad a escala | Alta | Manejable |
| Tolerancia a fallos | Baja (fallo único afecta todo) | Alta (fallos aislados) |
Los microservicios no son siempre la mejor opción. Son adecuados cuando:
Para proyectos pequeños o en fases tempranas, a menudo es más recomendable comenzar con un monolito modular (modular monolith) y migrar a microservicios cuando la complejidad y el tamaño del equipo lo justifiquen.