Hemos llegado al final. TechCorp ha pasado de un monolito con cinco problemas medibles (01-05) a seis servicios operados con SLOs, desplegados once veces al día y asegurados por capas; hemos contado la migración (08-01), escrito el sistema completo (08-02) y lo hemos desplegado y operado (08-03). Esta última lección no añade nada nuevo al sistema: destila lo aprendido para que te lo lleves a tu propio contexto. Primero, las lecciones de TechCorp organizadas por dimensión, cada una en la forma más honesta posible ("qué hicimos, qué salió mal, qué haríamos distinto"). Después, el catálogo de antipatrones que hemos visto y cómo reconocerlos a tiempo. Luego, una lista consolidada de buenas prácticas con la lección donde se explica cada una, lo que TechCorp haría en su fase 2 y con qué criterio, y una guía para el alumno: cómo decidir, por dónde empezar, cómo practicar con el entorno del curso y qué leer después. Y el cierre: el recorrido módulo a módulo y las palabras finales de Marta y Luis.

Contenido

  1. Lecciones aprendidas por dimensión
  2. Catálogo de antipatrones y cómo detectarlos
  3. Lista consolidada de mejores prácticas
  4. Qué haría TechCorp en la fase 2
  5. Guía para el alumno: aplicar el curso a tu contexto
  6. Lecturas y recursos recomendados
  7. Cierre del curso (en la conclusión)

  1. Lecciones aprendidas por dimensión

Cada tabla resume una dimensión del curso. La columna "qué haríamos distinto" es la más útil: es lo que TechCorp escribiría en el postmortem del proyecto.

1.1 Organización y equipos

Qué hicimos Qué salió mal Qué haríamos distinto
Reorganizar en cuatro equipos por capacidad de negocio (Experiencia de compra, Pedidos, Pagos y comunicaciones, Plataforma) antes de extraer nada; ley de Conway aplicada a propósito (02-01, 08-01 fase 0). El equipo de Plataforma fue cuello de botella los primeros meses: todos le pedían manifiestos, colas y usuarios de BD. Empezar la plantilla, el workflow reutilizable y el "añadir un servicio" del runbook (08-03 §10) en la fase 0, no en la 2; Plataforma como proveedor de autoservicio desde el primer día.
Propiedad de extremo a extremo: cada equipo despliega, opera y hace guardia de lo suyo; guardia rotatoria entre los cuatro equipos, solo alertas critical con runbook (06-05 §8). Al principio la guardia recibía alertas por causas (CPU alta, pod reiniciado) y se quemó; y un servicio (servicio-descuentos) nació sin dueño claro. Alertas por síntoma y SLO desde el primer servicio; regla "sin dueño no hay servicio" (el CODEOWNERS y el Application de Argo lo hacen explícito).
Marta fijó restricciones claras (no parar la tienda, valor por trimestre, dos BD, un lenguaje) y midió resultados (08-01 §10). La línea base de disponibilidad no existía: el "antes" es una estimación. Instrumentar el monolito con SLIs antes de la primera fase; medir es parte de la fase 0.

1.2 Diseño

Qué hicimos Qué salió mal Qué haríamos distinto
Bounded contexts con DDD estratégico; "producto" y "cliente" distintos en cada contexto; ACL traductorProducto; sin shared kernel (02-03). La primera versión de pedido.creado llevaba el precio de Catálogo sin ACL; un cambio de formato lo rompió en staging. ACL en cada frontera desde el primer contrato, aunque parezca burocracia.
Una base de datos por servicio, esquemas y usuarios svc_* como paso intermedio, ids opacos con prefijo, clientes_ref por eventos, migración sin dual write (02-04). Se intentó el dual write en el catálogo (08-01 §11) y hubo que tirarlo. Poner por escrito "una escritura, en el dueño; la copia, por eventos" en la fase 0.
Saga por coreografía con máquina de estados explícita, compensaciones como eventos de negocio, vigilante y reconciliación (02-05, 06-03). INC-2031: la saga sin alertas de síntoma ni DLQ bien diseñada se atascó 40 minutos. Vigilante, DLQ con reintento diferido, alerta de saga tardía y runbook antes del corte de la fase 5, no después del incidente.
Tamaño de servicio por capacidad de negocio: seis servicios, no sesenta (02-01). servicio-descuentos (nanoservicio) añadió latencia y despliegues sin autonomía; se reabsorbió. La pregunta "¿tiene datos y ciclo de vida propios y un equipo que lo quiera?" antes de crear un repositorio.
Monolito modular primero: devolver las escrituras de stock y pagos a su dueño dentro del monolito (02-02, 08-01 fase 0). Nada: fue el mejor trabajo invisible del proyecto. Hacerlo aún más: introducir las abstracciones (RepositorioProductos, ReservaStock) de las seis fronteras en la fase 0.

1.3 Comunicación

Qué hicimos Qué salió mal Qué haríamos distinto
Contratos primero (OpenAPI, AsyncAPI), /v1/, RFC 7807 con codigo, 202 + ETag, Idempotency-Key (03-01, 03-06). El cambio de 201 a 202 en POST /pedidos sorprendió al front-end; se avisó tarde. Los cambios de contrato visibles al cliente entran en la hoja de ruta con dos sprints de aviso y Deprecation desde el día uno.
Eventos con sobre estándar, topic exchange, una cola por consumidor con DLQ, at-least-once + idempotencia (03-02, 02-05). El binding de Pagos y Notificaciones a pedido.creado no estaba en el diseño inicial (08-02 §4-5): apareció al implementar. Diseñar el mapa de eventos completo (productor, consumidores, carga mínima) con el event storming, y validarlo con pactos de mensajes antes de la primera cola.
Gateway delgado: enrutado, JWT, rate limit, cabeceras internas; nada de negocio (03-04, 07-01). Alguien propuso "componer el detalle del pedido en el gateway"; se rechazó a tiempo. Mantener la regla escrita: la composición vive en un BFF o en el servicio, nunca en el gateway.
Versionado: URI para incompatibles, añadir sin quitar, Sunset, upcasting de eventos (03-06). Ninguna rotura de contrato en producción gracias a Pact; dos en staging. Nada relevante; quizá adoptar antes los pactos de mensajes.

1.4 Implementación

Qué hicimos Qué salió mal Qué haríamos distinto
Plantilla + librería técnica versionada (plantilla-servicio-node, @techcorp/comun-http); código de negocio nunca compartido (04-01, 02-02 §6). Durante dos meses el ci.yml se copió tres veces con diferencias (08-01 §11); el outbox estuvo en Pedidos hasta que Inventario lo necesitó. La regla de Luis literal: automatizar/extraer antes del segundo uso, no del cuarto.
Configuración validada al arrancar con zod, fail-fast, sin process.env fuera de config.js, secretos por Secret/ESO (04-03). Un CATALOGO_REMOTO mal escrito en un ConfigMap tumbó un pod en staging… y config.js lo detectó en el arranque, que es el objetivo. Nada.
Pirámide de pruebas con dobles inyectados, Testcontainers, Pact HTTP y de mensajes, una E2E (04-05, 08-02 §9). Los pactos de mensajes llegaron después de INC-2031. Pactos para eventos desde el primer consumidor de eventos (fase 2).
Idempotencia en todas partes: procesarUnaVez, Idempotency-Key, UNIQUE (pedido_id), UNIQUE (pedido_id, tipo), upsert (02-05 §8, 08-02). Ningún cobro ni correo duplicado en producción. Nada; es la práctica que más veces nos salvó.

1.5 Plataforma

Qué hicimos Qué salió mal Qué haríamos distinto
Contenedores multi-stage, USER node, sin latest, imágenes por sha y semver, Trivy y cosign (05-01, 07-04). Nada grave. Digest en los overlays de prod en lugar de etiquetas, desde el principio.
Kubernetes con Kustomize por servicio y entorno, Helm para terceros, sondas, securityContext, PDB, HPA/KEDA (05-02, 06-04, 07-04). El primer HPA de Catálogo por CPU sola oscilaba; hizo falta la métrica de peticiones. Autoescalar por la métrica que refleja la carga real (peticiones, longitud de cola), CPU como respaldo.
GitOps con Argo CD en prod, cd.yml en staging, can-i-deploy como puerta (05-03). Un kubectl scale manual en campaña revertido por selfHeal (08-03 §7). Educar: "producción se cambia por PR"; y el overlay de campaña desde el primer Black Friday.
Despliegues progresivos: rolling con maxUnavailable: 0, canary para Pedidos y Pagos, blue-green del gateway, expand/contract (05-04). El canary por peso HTTP no detecta consumidores lentos (08-03 ej. 2). Panel canary vs estable con métricas de consumidores por version; Argo Rollouts cuando haya análisis automático.
Sin mesh en la fase 1 (05-05). Nada: la decisión se sostuvo. Nada; revisitar en la fase 2 (apartado 4).

1.6 Operación

Qué hicimos Qué salió mal Qué haríamos distinto
Observabilidad: logs pino con redact, métricas RED y de negocio, Loki, trazas OpenTelemetry con traceparent por el outbox, correlación (06-01, 06-02). La cardinalidad tumbó Prometheus 25 minutos (08-01 §11). Regla de etiquetas acotadas y sample_limit en la plantilla desde el primer servicio.
Resiliencia: timeouts, reintentos con backoff solo de lo transitorio, circuit breaker, bulkhead, colas de reintento con TTL y DLQ, vigilante y reconciliación (06-03). Pagos reintentaba en bucle con prefetch(1) hasta INC-2031. Los patrones de 06-03 en comun-http antes del primer consumidor que hable con un tercero.
SLOs y alertas por burn rate, Alertmanager por equipo, runbooks versionados, severidades, postmortems sin culpa, política de presupuesto de error (06-05). Los SLOs llegaron en el módulo 6, cuando ya había cinco servicios en producción. SLO y alerta de síntoma para cada servicio al extraerlo, como parte de su definición de "hecho".
Escalado por métrica correcta y pruebas de carga con k6 antes de cada campaña (06-04). Nada grave; el primer Black Friday fue el gran éxito del proyecto. Nada.

1.7 Seguridad

Qué hicimos Qué salió mal Qué haríamos distinto
Identidad portable: Keycloak, JWT con clienteId, verificación en gateway y en cada servicio, regla del propietario (404), client credentials (07-01). Keycloak llegó en la fase 5 federando el monolito; hubo dos semanas de doble sesión incómodas. Keycloak en la fase 0 delante del monolito: la identidad es prerrequisito, como el gateway.
Capas: TLS en el borde con cert-manager, RabbitMQ amqps con usuario por servicio, BD verify-full, webhook HMAC; mTLS pospuesto (07-02). Ninguna brecha; el mTLS sigue pendiente. Nada; el mesh de la fase 2 lo cierra.
Código: zod estricto, helmet, gitleaks, RGPD (datos personales solo en pedido.creado, retención, cliente.eliminado), auditoría inmutable (07-03). La decisión RGPD llegó tarde y obligó a destinatarios en Notificaciones (08-02 §5). Minimización de datos en eventos decidida al diseñar el mapa de eventos.
Plataforma endurecida: securityContext completo, PSA restricted, ESO + Vault, OIDC en CI, NetworkPolicies deny-all, RBAC por ServiceAccount (07-04). PSA en audit, no enforce; ESO no cubre todos los servicios aún. Nada nuevo: son las tareas de fase 2 ya listadas en SEGURIDAD.md.

  1. Catálogo de antipatrones y cómo detectarlos

Todos han aparecido en el curso, casi todos en TechCorp. La columna "cómo detectarlo" es una prueba que puedes aplicar a tu sistema mañana.

Antipatrón Qué es Cómo detectarlo Dónde lo vimos
Monolito distribuido Servicios separados que hay que desplegar juntos o que comparten esquema "¿Un cambio de esquema en A obliga a desplegar B?"; "¿hay un orden de despliegue obligatorio?" (01-04 §7) 01-04, 02-01
Base de datos compartida Dos servicios leen/escriben las mismas tablas Matriz tabla × servicio con más de una E, o L ajenas sin contrato (02-02 §3.3) 02-02, 02-04
Nanoservicios / servicios de entidad Un servicio por tabla o por función "¿Tiene datos, ciclo de vida y equipo propios?"; llamadas síncronas encadenadas para cualquier caso de uso 02-01, servicio-descuentos (08-01)
Gateway gordo Lógica de negocio, composición o transformaciones en el gateway El repositorio del gateway crece con cada funcionalidad; PRs de equipos de negocio en él 03-04
Dual write Escribir en dos almacenes (o BD + broker) sin transacción común Discrepancias intermitentes en sombra; eventos "perdidos" sin explicación 02-04 §6, 02-05 §7, 08-01 §11
Sincronía en cadena A llama a B que llama a C en la petición del cliente Latencia p99 = suma; una dependencia caída tumba todo el flujo; trazas con más de 3 saltos síncronos 02-05, 03-02, 06-02
Sin idempotencia Reintentos que duplican efectos (dos cobros, dos correos) Reentregas de RabbitMQ o reintentos de red producen filas duplicadas; no hay UNIQUE de negocio 02-05 §8, 08-02
Alertar por causas Páginas por CPU, reinicios, colas con 1 mensaje La guardia recibe alertas que no requieren acción; alertas sin runbook 06-05 §6
Métricas de alta cardinalidad Ids o rutas sin plantilla como etiquetas Prometheus con memoria creciente; count({__name__=~".+"}) en millones 06-01 §11, 08-01 §11
Secretos en la imagen o en git Credenciales en Dockerfile, .env versionado, Secret en YAML "porque es base64" gitleaks; docker history muestra el secreto; kubectl get secret -o yaml en el repositorio 05-01, 07-03 §7, 07-04 §4
Librería de modelos compartida Un paquete @techcorp/modelos que todos importan Un cambio en Producto obliga a redesplegar seis servicios 01-04, 02-02 §6
Extraer el core primero Empezar por el servicio que depende de todos Nace con N llamadas al monolito y sin contratos 02-02 §5
Reintentar todo, inmediatamente nack con requeue en bucle, reintentos de 4xx Colas atascadas por un mensaje; x-intentos inexistente 03-02, 06-03, INC-2031
latest y despliegues manuales Imágenes mutables, kubectl apply desde portátiles Nadie sabe qué versión corre; drift respecto a git 05-01 §5, 05-03 §6
Sin línea base Migrar sin medir el "antes" Imposible demostrar mejora ni detectar regresión 08-01 §10

  1. Lista consolidada de mejores prácticas

Veinticinco puntos, agrupados, con la lección de referencia. Úsala como checklist de revisión de arquitectura o de un servicio nuevo.

Decisión y diseño

  1. Adopta microservicios por problemas medibles, no por moda; construye los cuatro prerrequisitos sobre el monolito y modularízalo primero (01-04, 02-02, 08-01 fase 0).
  2. Corta por capacidades de negocio y bounded contexts; valida con event storming y la matriz tabla × área (02-02, 02-03).
  3. Un servicio = sus datos: base de datos (o esquema) propia, ids opacos, sin FK cruzadas, réplicas de lectura por eventos (02-04).
  4. Sustituye la transacción distribuida por una saga con máquina de estados explícita, compensaciones como eventos y un vigilante (02-05, 06-03 §9).
  5. Extrae en orden de valor/riesgo/dependencias con strangler fig tras un gateway y branch by abstraction con flags; nunca borres lo antiguo el día del corte (02-02, 08-01).

Comunicación 6. Contratos primero (OpenAPI/AsyncAPI), errores RFC 7807 con codigo, 202 para procesos asíncronos, ETag para polling (03-01). 7. Eventos con sobre estándar (eventoId, tipo, version, ocurridoEn), topic exchange, cola por consumidor con reintento diferido y DLQ (03-02, 06-03 §8). 8. Outbox transaccional para publicar; procesarUnaVez + idempotencia de negocio (UNIQUE) para consumir; Idempotency-Key en los POST (02-05 §7-8, 04-04, 08-02). 9. Gateway delgado; composición en BFF o servicio; ACL en cada frontera (03-04, 02-03). 10. Versiona: añade sin quitar, /v2/ solo para incompatibles, Deprecation/Sunset, upcasting de eventos, pactos HTTP y de mensajes con can-i-deploy (03-06, 04-05, 05-03 §4).

Implementación 11. Plantilla de servicio + librería técnica versionada; el negocio no se comparte (04-01, 02-02 §6). 12. crearApp sin listen, inyección de dependencias por parámetro, capas hacia dentro (04-02). 13. Configuración validada al arrancar, fail-fast, secretos fuera del código y de la imagen (04-03, 07-03 §7). 14. Pirámide: unitarias del dominio, componente con dobles, integración con Testcontainers, contrato con Pact, una E2E (04-05). 15. Ninguna llamada externa dentro de una transacción; transacciones cortas y consulta por clave de idempotencia ante la duda (01-05, 08-02 §4).

Plataforma y despliegue 16. Imágenes multi-stage, no root, etiquetadas por sha y semver, escaneadas y firmadas; nunca latest (05-01, 07-04 §2). 17. Kustomize base + overlays por entorno; Helm para terceros con values versionados; sondas, securityContext, PDB, requests reales (05-02, 06-04, 07-04). 18. GitOps: producción cambia por PR; Argo CD sincroniza; rollback = revertir commit (05-03 §6). 19. Despliegues progresivos por servicio (rolling, canary, blue-green) con expand/contract y compatibilidad de eventos (05-04). 20. Workflow de CI reutilizable y versionado; la regla de Luis (05-03 §11).

Operación y seguridad 21. Logs estructurados con redact, métricas RED y de negocio con etiquetas acotadas, trazas con contexto propagado por HTTP y por eventos (06-01, 06-02). 22. Timeouts siempre, reintentos solo de lo transitorio con backoff, circuit breaker, bulkhead, DLQ con runbook (06-03). 23. SLOs con presupuesto de error, alertas por síntoma y burn rate, guardia con runbooks, postmortems sin culpa con acciones (06-05). 24. Identidad portable (OIDC/JWT) verificada en el gateway y en cada servicio; autorización por rol, scope y propietario; TLS en todas partes; webhooks firmados (07-01, 07-02). 25. Validación estricta de entrada, RGPD por diseño (minimización, retención, supresión), auditoría inmutable, secretos por operador, NetworkPolicies deny-all, RBAC mínimo, y una lista de pendientes honesta (07-03, 07-04).

  1. Qué haría TechCorp en la fase 2

Nada de esto es urgente; cada punto tiene un criterio que dice cuándo abordarlo. Es la diferencia entre una hoja de ruta y una lista de deseos.

Iniciativa Qué aporta Criterio para abordarlo Lección
Service mesh (Linkerd) con mTLS Identidad criptográfica entre servicios, canary por peso exacto interno, reintentos/timeouts uniformes Cuando la auditoría de Pagos exija mTLS, o cuando haya más de ~12 servicios y los patrones de comun-http diverjan 05-05, 07-02 §7
Event sourcing selectivo en Pedidos Historial completo del pedido, reconstrucción de vistas, auditoría natural Si negocio pide "qué pasó exactamente con este pedido" a menudo, o si aparecen más de tres vistas de lectura distintas; nunca para todo el sistema 02-05 §10
gRPC Pedidos ↔ Inventario Reserva síncrona de baja latencia para el checkout con "stock en tiempo real" Si la saga por eventos deja de ser aceptable para la experiencia de compra (comprobación de stock en el carrito), no antes 03-03
GraphQL en el BFF para la web Un solo endpoint para pantallas compuestas Cuando la web tenga tantas pantallas compuestas como la app; el bff-movil ya lo demuestra 03-03, 03-04
TypeScript en la plantilla Contratos tipados desde OpenAPI/AsyncAPI, menos errores de forma Cuando el equipo lo domine y la plantilla lo traiga; migrar servicio a servicio, empezando por comun-http 04-01
Go para Inventario Menor consumo y latencia en el servicio más "de sistema" Solo si el coste de Inventario o su latencia p99 se convierten en problema medido; el segundo lenguaje debe justificarse con datos (regla de Marta) 04-01
Plataforma interna (IDP): Backstage o similar Catálogo de servicios, plantillas con un clic, dueños, SLOs y runbooks en un sitio Cuando haya más de ~10 servicios o un segundo dominio de negocio; hoy plataforma/README.md basta 04-01, 08-03
FinOps Etiquetas de coste por equipo/servicio, informes mensuales, presupuestos por SLO Ya: empezar con la tabla de 08-03 §11 etiquetada por servicio; automatizar cuando la factura supere ~5.000 €/mes 08-03 §11
Orquestación de la saga Un coordinador si el flujo crece Solo si aparecen las señales de 02-05 §6 (más de 6 pasos, ramas condicionales, "¿en qué paso está?" frecuente) 02-05
Argo Rollouts / Flagger Canary con análisis automático de métricas Cuando los canary manuales pasen de dos al día 05-04
Pendientes de SEGURIDAD.md cosign en admisión, PSA enforce, ESO para todos, mTLS Trimestre siguiente, en este orden 07-04 §10

  1. Guía para el alumno: aplicar el curso a tu contexto

Decidir. Vuelve a la matriz de 01-04 y responde con datos, no con opiniones:

Pregunta Si la respuesta es "sí" Si es "no"
¿Tenéis varios equipos por capacidad de negocio que se estorban en el mismo código y las mismas tablas? Señal a favor Un equipo pequeño rinde más con un monolito modular
¿CI, contenedores, observabilidad y propiedad de extremo a extremo funcionan ya? Puedes empezar Construye eso primero sobre el monolito (fase 0 de 08-01)
¿Hay partes con perfiles de carga o disponibilidad muy distintos (el catálogo de TechCorp)? Hay un primer candidato claro Escala el monolito; es más barato
¿El dominio es estable y bien entendido? Los límites se pueden dibujar Los límites cambiarán; espera
¿La velocidad de entrega está frenada por el acoplamiento del despliegue (y no por otra cosa)? Microservicios ayudan Arregla la otra cosa (pruebas, procesos, deuda)

Cuatro o más "sí" con los prerrequisitos listos: extrae de forma incremental empezando por la razón más clara. Menos: monolito modular y revisión en seis meses. Y recuerda que la lista de 01-04 tiene señales de alarma (equipo de tres personas, "porque lo hace Netflix", sin automatización) que anulan todo lo demás.

Por dónde empezar (si decides seguir): en este orden, y sin saltarte ninguno: (1) los cuatro equipos —o los que tengas— con propiedad clara; (2) CI e imagen del monolito; (3) gateway delante y observabilidad mínima; (4) matriz tabla × área y monolito modular; (5) primera extracción por valor/riesgo/dependencias con carga inicial, eventos, sombra y flag; (6) SLO y alerta del servicio nuevo antes de darlo por hecho; (7) plantilla y librería antes del segundo servicio.

Cómo practicar. El entorno del curso está pensado para reproducirse:

  • Levanta TechCorp en local con el compose.yaml de 08-03 §2, obtén un token de Keycloak y sigue a ped-88213 por Jaeger, Grafana y Loki como en 08-03 §5. Rompe cosas: para servicio-pagos y observa el vigilante y la DLQ; publica un evento mal formado con publicarEvento.js y reprocésalo; agota el stock de p-802.
# Sesión de práctica típica (repositorios hermanos clonados: servicio-*, gateway, plataforma)
cd plataforma/local && docker compose up -d --wait                       # 19 contenedores; ~90 s
TOKEN=$(../scripts/token-keycloak.sh http://localhost:8180 techcorp pruebas-e2e ana.ruiz clave-de-pruebas)
docker compose stop servicio-pagos                                       # 1. rompe Pagos y crea un pedido: se queda en STOCK_RESERVADO
curl -s -X POST http://localhost:8080/api/v1/pedidos -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
     -H "Idempotency-Key: practica-$(date +%s)" -d '{"clienteId":"c-1024","lineas":[{"productoId":"p-501","cantidad":1}]}' | jq .id
#   → espera 10 min y verás pedido.cancelado (TIMEOUT_PAGO) del vigilante; o arranca Pagos antes y verás CONFIRMADO
docker compose start servicio-pagos
node ../../servicio-pedidos/scripts/publicarEvento.js stock.reservado '{"pedidoId":"ped-inexistente"}'   # 2. evento para un pedido desconocido → log, no DLQ
node ../../servicio-pedidos/scripts/publicarEvento.js pago.confirmado '{"pedidoId":"<un ped- en PENDIENTE>"}'   # 3. transición no permitida → transicion_ignorada en el log, estado intacto
#   Jaeger http://localhost:16686 · Grafana http://localhost:3000 · RabbitMQ http://localhost:15672 (mira pedidos.saga.dlq tras el paso 3 con un JSON roto)
docker compose down -v                                                                                     # base de datos limpia para la próxima sesión
  • Ejercicios de extensión propuestos, de menor a mayor: cupones y promociones (01-03, 02-02 ej. 2, 08-01 §11): primero como módulo de Pedidos, después decide con criterio si merece servicio; devoluciones: nuevo estado del pedido, pago.reembolsado como rama habitual, stock.repuesto, correo, auditoría; envíos: un servicio-envios que consuma pedido.confirmado, hable con un transportista ficticio (ACL, webhook firmado, reintentos) y publique pedido.enviado/pedido.entregado que Notificaciones y la analítica consuman; v2 de pedido.creado con upcasting y pactos de mensajes; Argo Rollouts para el canary de Pedidos con análisis de slo:pedidos_error_ratio.
  • Repite el módulo 6 sobre tu propia extensión: métricas, SLO, alerta, runbook y un game day en el que un compañero rompa algo sin avisar.

  1. Lecturas y recursos recomendados

Sin URLs (cambian); busca por título y proyecto. Libros:

  • Sam Newman, Building Microservices (2.ª ed.) y Monolith to Microservices: la referencia general y el manual del strangler fig que TechCorp siguió (módulos 1, 2 y 8).
  • Chris Richardson, Microservices Patterns: sagas, outbox, CQRS, API composition; el sitio microservices.io del autor cataloga los patrones (02-05, 03-04).
  • Eric Evans, Domain-Driven Design; Vaughn Vernon, Implementing Domain-Driven Design; Vlad Khononov, Learning Domain-Driven Design: bounded contexts, mapa de contextos, agregados (02-03).
  • Martin Kleppmann, Designing Data-Intensive Applications: consistencia, replicación, mensajería, la base teórica de 02-04 y 02-05.
  • Gregor Hohpe y Bobby Woolf, Enterprise Integration Patterns: mensajería, DLQ, idempotencia (03-02, 06-03).
  • Michael Nygard, Release It! (2.ª ed.): timeouts, circuit breaker, bulkhead, estabilidad (06-03).
  • Betsy Beyer y otros (Google), Site Reliability Engineering y The Site Reliability Workbook: SLOs, burn rate, guardias, postmortems (06-05).
  • Nicole Forsgren, Jez Humble y Gene Kim, Accelerate: las métricas DORA (05-03, 08-01 §10).
  • Matthew Skelton y Manuel Pais, Team Topologies: equipos alineados a flujo y equipo de plataforma (02-01, 08-04 §1.1).
  • Jez Humble y David Farley, Continuous Delivery; Marko Lukša, Kubernetes in Action: la base de los módulos 5 y 8.
  • Neal Ford, Mark Richards, Pramod Sadalage y Zhamak Dehghani, Software Architecture: The Hard Parts: granularidad, datos y sagas con trade-offs explícitos.

Documentación oficial y proyectos que conviene tener a mano: Node.js y Express; PostgreSQL y MongoDB; RabbitMQ (guías de fiabilidad, DLX y TTL); Docker y Compose; Kubernetes (conceptos, Kustomize), Helm, kind, KEDA, Argo CD y Argo Rollouts, ingress-nginx, cert-manager, External Secrets Operator; GitHub Actions; Prometheus, Grafana, Loki, OpenTelemetry (JavaScript SDK) y Jaeger; Keycloak; Pact (incluidos los pactos de mensajes) y el Pact Broker; Trivy y Sigstore/cosign; OWASP API Security Top 10; The Twelve-Factor App; y las especificaciones OpenAPI, AsyncAPI, RFC 7807 y W3C Trace Context.

Errores Comunes y Consejos

  • Convertir la lista de mejores prácticas en dogma. Cada punto del apartado 3 tiene una lección con su contexto y sus trade-offs; aplicado sin el contexto (por ejemplo, outbox en un servicio que no publica nada crítico) añade complejidad sin beneficio. Lee la lección antes de imponer la práctica.
  • Copiar la arquitectura final de TechCorp en lugar de su método. Seis servicios, RabbitMQ y Kubernetes son la respuesta a los cinco problemas de 01-05 con 25 técnicos; con tres personas y un dominio cambiante, la respuesta correcta de la matriz de 01-04 es un monolito modular.
  • Confundir "fase 2" con "pendiente". Mesh, event sourcing, gRPC o Go tienen un criterio de activación; abordarlos antes de que se cumpla es el "porque lo hace Netflix" que 01-04 avisaba.
  • Postmortem sin acciones o acciones sin fecha. Las tablas del apartado 1 son postmortems del proyecto; su valor está en la columna "qué haríamos distinto" convertida en tareas con dueño.
  • Practicar solo el camino feliz. El entorno local sirve para romper: para Pagos, agota stock, publica eventos mal formados, rota un secreto. Lo que no has visto fallar en local lo verás fallar en producción.
  • Consejo: guarda tu propia versión de las tablas del apartado 1 desde el primer día de tu proyecto, aunque estén casi vacías. La disciplina de rellenarlas cada trimestre vale más que cualquier herramienta.

Ejercicios

Ejercicio 1: Tu propia matriz

Aplica la matriz del apartado 5 a un sistema que conozcas (el de tu trabajo, un proyecto personal o, si no tienes ninguno, un sistema de reservas de un hotel con 4 técnicos). Responde a las cinco preguntas con datos concretos, indica qué recomendación sale y, si es "extraer", cuál sería el primer servicio y qué haría tu fase 0.

Ejercicio 2: Reconocer antipatrones

Un equipo describe su sistema así: "Tenemos ocho servicios en Kubernetes. Comparten una base de datos PostgreSQL con esquemas separados por servicio, pero el servicio de informes hace JOIN entre esquemas. Desplegamos los ocho juntos cada dos semanas porque un cambio en la librería modelos-comunes obliga a actualizar todos. Los servicios se llaman por HTTP en cadena y, cuando el de clientes tarda, todo tarda. Cada servicio reintenta las llamadas fallidas tres veces seguidas." Identifica todos los antipatrones del apartado 2 que aparecen, ordénalos por el daño que hacen y propón para cada uno la primera acción, con la lección de referencia.

Ejercicio 3: Priorizar la fase 2

Marta tiene presupuesto para dos iniciativas de la tabla del apartado 4 el próximo semestre. Con los datos del curso (08-01 §10-11, 08-03 §11, SEGURIDAD.md), elige dos, justifica con el criterio de cada una y explica por qué descartas al menos otras tres que parecen atractivas.

Soluciones

Ejercicio 1. No hay una única respuesta; la solución es el método. Para el hotel de 4 técnicos: (1) un equipo, sin estorbos → no; (2) probablemente sin CI completo ni observabilidad → no; (3) reservas y facturación tienen cargas parecidas; quizá el motor de disponibilidad en temporada alta → débil; (4) dominio conocido → sí; (5) la velocidad la frena la falta de pruebas, no el despliegue → no. Resultado: monolito modular con módulos por capacidad (reservas, facturación, disponibilidad, clientes), CI, contenedor, observabilidad y SLIs desde ya; revisar en 6-12 meses. Si en tu sistema real salen cuatro "sí" con prerrequisitos listos, el primer servicio es el que tenga la razón más clara y menos dependencias (el "catálogo" de tu dominio) y la fase 0 es la lista del apartado 5 ("por dónde empezar").

Ejercicio 2. Por daño: (1) Base de datos compartida (los JOIN del servicio de informes cruzan esquemas: cualquier cambio de esquema rompe informes) → matriz tabla × servicio y BD de lectura para informes alimentada por eventos (02-02 §3.3, 02-04 §8); (2) Librería de modelos compartida + monolito distribuido (ocho servicios desplegados juntos por modelos-comunes) → sustituir por contratos por servicio y una librería solo técnica versionada; cada servicio define sus DTOs (02-02 §6, 03-06); (3) Sincronía en cadena con reintentos inmediatos (todo tarda cuando tarda clientes; tres reintentos seguidos multiplican la carga: tormenta de reintentos) → timeouts con presupuesto, circuit breaker, reintentos con backoff solo de lo transitorio, y sustituir las llamadas no necesarias en la petición por eventos o réplicas de lectura (06-03, 02-04 §4, 03-02); (4) Despliegue conjunto cada dos semanas (síntoma, no causa) → desaparece al resolver 1-2; medir DORA para comprobarlo (05-03 §12). No aparecen (o no se sabe): gateway gordo, secretos, cardinalidad; preguntar.

Ejercicio 3. Una respuesta defendible: (a) FinOps — criterio "ya": la factura es de 2.760 €/mes con palancas identificadas de ~800 € (08-03 ej. 3); coste de la iniciativa bajo (etiquetas y un informe); retorno inmediato que además financia lo demás. (b) Pendientes de SEGURIDAD.md (cosign en admisión, PSA enforce, ESO para todos) — criterio "trimestre siguiente"; riesgo conocido, coste acotado, y desbloquea la auditoría de Pagos que a su vez activará el mesh. Descartes: mesh/mTLS ahora — su criterio (auditoría o >12 servicios) no se cumple aún y cuesta operar (05-05); event sourcing — nadie ha pedido el historial completo y la auditoría de 07-03 cubre lo sensible; Go para Inventario — no hay coste ni latencia medidos que lo justifiquen (regla de Marta); gRPC Pedidos↔Inventario — la saga cumple su SLO de 60 s con p95 de 3 s; IDP — con 6 servicios y un README, no compensa. Lo importante no son las dos elegidas sino que cada descarte se apoye en el criterio de la tabla y no en el atractivo de la tecnología.

Conclusión

El recorrido, módulo a módulo. En el módulo 1 aprendimos qué es un microservicio, qué se gana y qué se paga, cómo se compara con el monolito, cuándo tiene sentido dar el paso y conocimos a TechCorp: un monolito con cinco problemas y una función, crearPedido, que hacía seis cosas de cinco áreas. En el módulo 2 diseñamos: principios y acoplamientos, descomposición con event storming y la matriz de tablas, bounded contexts y el mapa de contextos, una base de datos por servicio y la migración sin dual write, y la saga por coreografía con outbox e idempotencia que sustituyó a la transacción. En el módulo 3 hicimos hablar a los servicios: contratos REST con 202, ETag e Idempotency-Key; RabbitMQ con su topología y sus DLQ; gRPC y GraphQL como candidatos; el gateway y el BFF; descubrimiento y sondas; versionado y pactos. En el módulo 4 escribimos código: la plantilla y la librería, servicio-catalogo, la configuración validada, servicio-pedidos con su outbox y sus consumidores, y la pirámide de pruebas. En el módulo 5 lo empaquetamos y desplegamos: Docker y Compose, Kubernetes con Kustomize, CI/CD con GitHub Actions, Pact Broker y Argo CD, despliegues progresivos, y la evaluación honesta del mesh. En el módulo 6 lo hicimos operable: logs, métricas y trazas; resiliencia y recuperación; escalado; SLOs, alertas, guardias, runbooks y el postmortem de INC-2031. En el módulo 7 lo aseguramos por capas: Keycloak y JWT, TLS y firmas, código validado y RGPD, plataforma endurecida. Y en el módulo 8 lo unimos: la migración contada en orden, los cuatro servicios que faltaban, el sistema desplegado y operado, y estas lecciones.

Palabras de Marta. "Cuando presenté el plan en julio de 2025 me preguntaron por qué no reescribíamos la tienda de una vez. Trece meses después, la respuesta está en los números que no tuvimos que explicar: ningún día sin vender, once despliegues al día, un incidente serio que duró cuarenta minutos y del que aprendimos más que de dos años de jueves por la noche. Pero lo que más valoro no está en la tabla: hoy cada equipo sabe qué es suyo, lo mide y lo mejora sin pedir permiso. Los microservicios fueron el medio; el fin era una organización que pudiera cambiar la tienda cada día sin miedo. Si tuviera que resumir el proyecto en una frase para otra CTO: no empieces por los servicios, empieza por los deberes; y no borres nada el día del corte."

Palabras de Luis. "Yo me quedo con tres cosas. La primera, que la mejor decisión técnica del año fue la menos vistosa: devolver las escrituras de stock y pagos a su dueño dentro del monolito antes de mover una línea de servidor. La segunda, que casi todo lo que nos salvó en producción era aburrido y estaba escrito antes de necesitarlo: el UNIQUE (pedido_id), el procesarUnaVez, el vigilante, la clave de idempotencia hacia la pasarela, la cola de reintento. Y la tercera, que la regla de 'si se hace más de una vez por servicio, se automatiza antes del segundo' es más fácil de decir que de cumplir —el ci.yml se copió tres veces— y aun así es la que hace que seis servicios los pueda operar un equipo de veinticinco personas. A quien esté empezando: leed crearPedido de 01-05 otra vez, ahora que sabéis en qué se convirtió. Todo el curso está en la distancia entre esas 80 líneas y ped-88213 cruzando cuatro bases de datos en tres segundos."

Para ti. Has recorrido el mismo camino que TechCorp, con sus decisiones y sus tropiezos. Lo que te llevas no es una lista de tecnologías —cambiarán— sino un método: medir antes de decidir, hacer los deberes antes de dividir, cortar por capacidades y datos, comunicar por contratos y eventos idempotentes, automatizar antes del segundo uso, desplegar en pequeño y a menudo, observar y acordar qué es "ir bien", asegurar por capas y aprender por escrito de cada incidente. Levanta TechCorp en tu portátil, rómpela, extiéndela con cupones, devoluciones o envíos, y después aplica el método a tu propio sistema, empezando por la fase 0. Los microservicios no son el destino; son una forma de que tu organización pueda cambiar su software con confianza, un pedido —y un despliegue— cada vez. Gracias por llegar hasta aquí, y buena suerte con tu propia migración.

Curso de Microservicios

Módulo 1: Introducción a los Microservicios

Módulo 2: Diseño de Microservicios

Módulo 3: Comunicación entre Microservicios

Módulo 4: Implementación de Microservicios

Módulo 5: Despliegue y Orquestación

Módulo 6: Monitoreo y Mantenimiento

Módulo 7: Seguridad en Microservicios

Módulo 8: Casos de Estudio y Ejemplos Prácticos

© Copyright 2026. Todos los derechos reservados