Guía de Arquitectura de Microservicios
Implementación progresiva de microservicios con Fox Framework sobre las primitivas descritas en docs/microservices.mdx.
Contenido
- Principios
- Estrategia de Desglose
- Service Registry
- API Gateway
- Load Balancing + Circuit Breaker
- Comunicación Asíncrona (Event Bus)
- Observabilidad
- Deployment y Versionado
Principios
- Límite claro por contexto de dominio
- Deploy independiente, datos propios (Database per Service)
- Comunicación resiliente (retries + timeouts + breaker)
- Observabilidad unificada (logs, métricas, tracing)
Estrategia de Desglose
- Monolito modular (extrae módulos internos)
- Extrae primer servicio de baja criticidad (ej. reporting)
- Implementa gateway + registry
- Mide latencia, errores, throughput
- Itera extracción de dominios core
Service Registry
import { ServiceRegistryFactory } from 'fox-framework';
export const registry = ServiceRegistryFactory.create({ provider: 'consul', connection:{ host:'consul', port:8500 } });
await registry.register({ id:'user-svc-1', name:'user-service', version:'1.0.0', address:'user-svc', port:3001, healthCheck:{ endpoint:'/health', interval:'10s' } });Descubrimiento:
const instances = await registry.discover('user-service');API Gateway
import { ApiGatewayFactory } from 'fox-framework';
const gateway = ApiGatewayFactory.create({ port:8000, cors:true, registry });
gateway.route({ path:'/users', service:'user-service', methods:['GET','POST'], rewrite:'/api/users' });
gateway.start();Beneficios: centraliza auth, rate limiting, agregación.
Load Balancing + Circuit Breaker
const lb = LoadBalancerFactory.create({ algorithm:'round-robin', registry, serviceName:'payment-service' });
const breaker = CircuitBreakerFactory.create({ name:'payment-breaker', failureThreshold:5, resetTimeout:30000, timeout:3000 });
async function callPayment(path:string){
const inst = await lb.next();
return breaker.execute(async ()=> {
const res = await fetch(`http://${inst.address}:${inst.port}${path}`); if(!res.ok) throw new Error('bad'); return res.json();
});
}Comunicación Asíncrona (Event Bus)
Patrón: servicios publican eventos de dominio; consumidores reaccionan.
const eventBus = microservices.getEventBus();
await eventBus.publish('user.created', { id:user.id, email:user.email });
eventBus.subscribe('payment.completed', async (evt)=> { await orderService.markPaid(evt.payload.orderId); });Ventajas: desacoplamiento temporal, escalado independiente.
Observabilidad
Mínimo por servicio:
- Logger estructurado con
service,version,correlationId - Endpoint
/health(readiness + liveness) - Métricas Prometheus (
http_requests_total, latencias p95/p99) - Tracing (Jaeger / OTEL) propagando headers (
traceparent)
Middleware de correlación:
app.use((req,res,next)=>{ req.correlationId = req.headers['x-correlation-id']||crypto.randomUUID(); res.setHeader('x-correlation-id', req.correlationId); next(); });Deployment y Versionado
Versiona cada servicio (semver) y publica imagen Docker: org/user-service:1.2.0.
Estrategias de actualización:
- Patch silencioso (bugfix: 1.2.1)
- Minor con backwards compat (1.3.0)
- Major requiere coordinación de contratos
Contratos (API) versionados vía path: /v1/users, /v2/users.
Anti-Patrones a Evitar
- Base de datos compartida directa
- Chattiness excesiva (desnormaliza datos necesarios)
- Falta de timeouts (peticiones colgadas)
- Dependencias cíclicas entre servicios
Roadmap Evolutivo
- Observabilidad base
- Circuit breakers / retries
- Event sourcing (si aplica)
- Multi-región / failover