Be Software Architecture Wise
Be Wise Apps

Read in English · Lire en français · Auf Deutsch lesen

Capítulo 6 de 12 · De intermedio a avanzado

Estilos arquitectónicos II: sistemas distribuidos

Este capítulo lleva la arquitectura a través de la red. Explica cuándo merece la pena pagar el costo de distribuir un sistema, las falacias que lo hacen más difícil de lo que parece y los principales estilos distribuidos: la arquitectura basada en servicios, la arquitectura orientada a servicios, los microservicios, la arquitectura dirigida por eventos, serverless y la arquitectura basada en espacios. Después trata los mecanismos de los que dependen todos ellos: la comunicación síncrona y asíncrona y el diseño de API, los modelos de consistencia y el teorema CAP, y las transacciones distribuidas con sagas y el patrón outbox. Está escrito para desarrolladores y arquitectos que diseñan o revisan sistemas formados por muchos servicios, y es preciso en cuanto a los fallos, las garantías de entrega y la consistencia.

Introducción en video al capítulo 6

7 min · narrado en inglés, con subtítulos
Solo escuchar (audio)
Leer la transcripción

Te damos la bienvenida al Capítulo 6: Estilos arquitectónicos, segunda parte, sistemas distribuidos. El Capítulo 5 describió estilos en los que todo el sistema se despliega como una sola unidad. Este capítulo lleva las mismas preguntas a través de una red. Explica cuándo merece la pena pagar el costo de distribuir un sistema, los principales estilos distribuidos y los mecanismos de los que dependen todos ellos. Y es preciso en cuanto a los fallos, las garantías de entrega y la consistencia.

Hoy casi todo sistema de cierto tamaño está distribuido de algún modo. Una app para dispositivos móviles se comunica con servicios de backend, que llaman a proveedores de pago, servicios de mapas e intermediarios de mensajes, y los propios servicios se ejecutan en muchas máquinas. Dividir un sistema puede aportar escalado independiente, aislamiento de fallos, lanzamientos independientes y equipos autónomos. También trae problemas que no pueden darse dentro de un solo proceso: mensajes perdidos o duplicados, servicios que están lentos en lugar de caídos, datos que no coinciden entre copias y fallos en máquinas de las que no sabías que dependías.

El capítulo tiene un nivel de intermedio a avanzado. Está escrito para desarrolladores y arquitectos que diseñan o revisan sistemas formados por muchos servicios. Se apoya en los estilos del Capítulo 5 y en las cualidades del Capítulo 2, ahora en condiciones de red. En particular, usa la disponibilidad en serie y en paralelo, el acoplamiento y la ley de Conway, y el cuanto de arquitectura, el monolito modular y los contextos delimitados. Y conduce al Capítulo 7, que trata la parte más difícil de la distribución: los datos.

La idea más importante del capítulo es que distribuir es un intercambio, no una mejora. Cada beneficio se paga con latencia, consistencia, observabilidad y esfuerzo operativo. Un buen arquitecto sabe decir qué beneficio se está comprando, a qué precio y por qué no basta con una opción más barata dentro de un monolito.

El capítulo va del porqué al cómo. La sección seis punto uno expone las razones para distribuir, las ocho falacias de la computación distribuida y el fallo parcial, y te da la aritmética para poner precio al intercambio antes de comprometerte con él. La sección seis punto dos trata la arquitectura basada en servicios, un término medio pragmático de unos pocos servicios de dominio de grano grueso, y la clásica arquitectura orientada a servicios, incluido por qué cayó en desuso. La sección seis punto tres trata los microservicios: servicios alineados con contextos delimitados, despliegue independiente, una base de datos por servicio, cómo decidir el tamaño que debe tener un servicio, y el monolito distribuido. La sección seis punto cuatro trata la arquitectura dirigida por eventos: eventos y comandos, intermediarios y mediadores, garantías de entrega, y consumidores que pueden recibir sin riesgo el mismo mensaje dos veces.

Esta es la aritmética de la sección seis punto uno. Hacer un pedido pasa por cinco servicios: el API gateway y después los de pedidos, carta, precios y pagos. Cada uno espera a que responda el siguiente, y cada uno por sí solo está disponible el noventa y nueve punto nueve por ciento del tiempo. Pero las disponibilidades se multiplican. Juntos dan una ruta de solicitud de solo un noventa y nueve y medio por ciento aproximadamente: unas tres punto seis horas de inactividad al mes. Y las latencias se suman. Con veinte milisegundos de trabajo en cada servicio, más un poco por cada salto de red, la mediana es de unos ciento diez milisegundos. Cinco servicios respetables por separado han producido una ruta de solicitud mucho más débil. Ese es el precio de la distribución, calculado sobre el papel antes de construir nada.

Este diagrama muestra el fallo parcial, el problema definitorio. Un servicio de pedidos pide a un servicio de pagos que autorice veinticuatro libras con cincuenta, y espera la respuesta. Pueden salir mal tres cosas distintas. La solicitud se pierde, y no se hizo ningún cargo. El servicio de pagos se cae o se bloquea, y nadie lo sabe. O se pierde la respuesta, y la tarjeta sí recibió el cargo. Para quien llama, las tres parecen idénticas: no llega respuesta antes del timeout. Así que toda operación que pueda reintentarse debe ser idempotente, lo que significa que hacerla dos veces tiene el mismo efecto que hacerla una.

La segunda mitad pasa a los mecanismos de los que depende todo estilo distribuido. La sección seis punto cinco compara la comunicación síncrona y la asíncrona y el acoplamiento que crea cada una, y trata el diseño de API, el versionado y las pruebas de contrato. La sección seis punto seis trata lo que pueden esperar quienes leen datos copiados: los modelos de consistencia, lo que dice realmente el teorema CAP, y PACELC. La sección seis punto siete explica por qué se evita la confirmación en dos fases entre servicios, y cómo las sagas, las transacciones compensatorias y el patrón outbox mantienen correctos los procesos de negocio sin ella. La sección seis punto ocho cierra con dos estilos para perfiles de carga particulares: las funciones serverless, que escalan hasta cero, y la arquitectura basada en espacios, que mantiene los datos en memoria para sobrevivir a picos extremos, como la puesta a la venta de entradas.

Tres hábitos recorren todas las secciones. Primero, cuenta las dependencias síncronas, no los servicios. El número de cosas que deben funcionar todas en el mismo momento para que una solicitud tenga éxito decide su disponibilidad y su latencia. Segundo, da por hecho que los mensajes se pierden, se retrasan, se duplican y llegan desordenados, y diseña los receptores para que un mensaje repetido no cause daño. Tercero, decide quién es el propietario de cada dato, porque la propiedad decide dónde son posibles las transacciones y dónde hay que gestionar la consistencia entre servicios. El Capítulo 7 desarrolla ese hábito en un tratamiento completo de la arquitectura de datos.

Si el tema es nuevo para ti, lee primero el resumen inicial de cada sección y los recuadros titulados Si eres nuevo en esto. Los ingenieros con experiencia encontrarán precisión donde importa. El capítulo se lee en unas tres horas y media. Hay dos ejemplos que se repiten. La plataforma de reparto de comida muestra el diseño distribuido corriente. Un sistema de venta de entradas para una gira por estadios muestra lo que cambia cuando decenas de miles de personas quieren los mismos pocos asientos en el mismo segundo. Cada sección termina con unas cuantas preguntas de autoevaluación. Respóndelas mentalmente antes de mirar. Cuando estés listo, haz la prueba opcional del capítulo: veinte preguntas de opción múltiple y dos respuestas escritas, en unos cuarenta y cinco minutos. La nota de aprobado es el ochenta por ciento.

Ese es el mapa del Capítulo 6. Empieza por la sección seis punto uno, donde sopesamos las razones para distribuir frente a las falacias que lo hacen más difícil de lo que parece. Nos vemos allí.

Descargar el capítulo (PDF)Leer en la app

De un vistazo

Aprenderás a

  • Explicar las razones legítimas para distribuir un sistema y los costos que conlleva cada una.
  • Describir las ocho falacias de la computación distribuida y el fallo parcial, y diseñar respuestas a ellos.
  • Calcular la disponibilidad y la latencia de una cadena de llamadas síncronas y proponer cambios que las mejoren.
  • Comparar la arquitectura basada en servicios, la SOA clásica y los microservicios, y elegir entre ellos para una organización concreta.
  • Decidir la granularidad de los servicios sopesando los desintegradores frente a los integradores, y reconocer el monolito distribuido.
  • Distinguir eventos, comandos y mensajes, las topologías de intermediario (broker) y de mediador, y los cuatro patrones de eventos de Fowler.
  • Explicar las garantías de entrega, por qué "exactamente una vez" exige una definición cuidadosa y cómo funcionan los consumidores idempotentes.
  • Elegir estilos de comunicación, niveles de consistencia y patrones de transacción (sagas, outbox) para flujos de trabajo distribuidos.

Antes de empezar

Capítulos 0 a 5, en especial la disponibilidad en serie y en paralelo (Capítulo 2, Sección 2.5), el acoplamiento y la ley de Conway (Capítulo 3), y el cuanto de arquitectura, el monolito modular y los contextos delimitados (Capítulo 5).

Tiempo

Unas 3½ horas de lectura; 45 minutos para la prueba.

Términos clave

sistema distribuido · fallo parcial · falacias de la computación distribuida · acoplamiento temporal · arquitectura basada en servicios · bus de servicios empresarial · microservicios · desplegabilidad independiente · base de datos por servicio · arquitectura dirigida por eventos · entrega al menos una vez (at-least-once) · consumidor idempotente · Teorema CAP · saga

Por qué importa este capítulo

El Capítulo 5 describió estilos en los que todo el sistema se despliega como una sola unidad. Este capítulo lleva las mismas preguntas a través de una red. Hoy casi todo sistema de cierto tamaño está distribuido de algún modo: una app para dispositivos móviles se comunica con servicios de backend, que llaman a proveedores de pago, servicios de mapas e intermediarios de mensajes (message brokers), y los propios servicios se ejecutan en muchas máquinas. Dividir un sistema puede aportar escalado independiente, aislamiento de fallos, lanzamientos independientes y equipos autónomos. También trae una clase de problemas que no pueden darse dentro de un solo proceso: mensajes perdidos o duplicados, servicios que están lentos en lugar de caídos, datos que no coinciden entre copias y fallos en máquinas de las que no sabías que dependías.

La idea más importante que debes llevarte es que distribuir es un intercambio, no una mejora. Cada beneficio se paga con latencia, consistencia, observabilidad y esfuerzo operativo, y un buen arquitecto sabe decir qué beneficio se está comprando, a qué precio y por qué no basta con una opción más barata dentro de un monolito. Las falacias de la computación distribuida y la aritmética de las cadenas de llamadas síncronas de la primera sección son las herramientas para poner precio a ese intercambio antes de comprometerse con él.

Cómo encajan las secciones

El capítulo va del porqué al cómo. La Sección 6.1 expone las razones para distribuir, las ocho falacias, el fallo parcial y los costos, y muestra con un ejemplo práctico cómo cinco servicios que cumplen cada uno una disponibilidad del 99.9% dan una ruta de solicitud de solo un 99.5% aproximadamente. Termina volviendo sobre el cuanto de arquitectura, que explica por qué las llamadas síncronas unen entre sí servicios desplegados por separado.

Las tres secciones siguientes son los principales estilos distribuidos, cada uno tratado como los estilos del Capítulo 5: definición y origen, un diagrama, cómo funciona, un ejemplo, una tabla de características, cuándo usarlo y los antipatrones habituales. La Sección 6.2 trata la arquitectura basada en servicios, un término medio pragmático de unos pocos servicios de dominio de grano grueso que a menudo comparten una base de datos, y la clásica arquitectura orientada a servicios de los buses de servicios empresariales y los modelos canónicos, incluido por qué cayó en desuso. La Sección 6.3 trata los microservicios: servicios alineados con contextos delimitados, desplegabilidad independiente, base de datos por servicio, patrones de apoyo como los API gateways y los service meshes, cómo decidir la granularidad, y el monolito distribuido y otros antipatrones. La Sección 6.4 trata la arquitectura dirigida por eventos: eventos y comandos, las topologías de intermediario (broker) y de mediador, las particiones y los grupos de consumidores de Kafka, las garantías de entrega y los consumidores idempotentes.

La segunda mitad pasa a los mecanismos de los que depende todo estilo distribuido. La Sección 6.5 compara la comunicación síncrona y la asíncrona y el acoplamiento que crea cada una, y trata REST, gRPC, GraphQL y la mensajería, las prácticas de diseño de API, el versionado y las pruebas de contrato. La Sección 6.6 trata lo que pueden esperar quienes leen datos replicados: los modelos de consistencia, desde la linealizabilidad hasta la consistencia eventual, el teorema CAP y lo que dice realmente, PACELC y los quórums. La Sección 6.7 explica por qué se evita la confirmación en dos fases entre servicios y cómo las sagas, las transacciones compensatorias y la bandeja de salida transaccional (transactional outbox) mantienen correctos los procesos de negocio sin ella. La Sección 6.8 cierra con dos estilos para perfiles de carga particulares: las funciones serverless, que escalan hasta cero y se facturan por invocación, y la arquitectura basada en espacios, que mantiene los datos en memoria para sobrevivir a picos extremos como la puesta a la venta de entradas.

Ejemplos recurrentes y cómo leer el capítulo

Hay dos ejemplos que se repiten. La plataforma de reparto de comida de los capítulos anteriores (clientes, restaurantes, repartidores, pagos) muestra el diseño distribuido corriente: aparece como cinco servicios de dominio, como un conjunto de microservicios, como un flujo del evento OrderPlaced y como una saga de pedido. Un sistema de venta de entradas para una gira por estadios muestra lo que cambia con una carga extrema y en picos, cuando decenas de miles de personas quieren los mismos pocos asientos en el mismo segundo.

El capítulo tiene un nivel de intermedio a avanzado. Presupone los Capítulos 0 a 5, en particular la disponibilidad en serie y en paralelo (Capítulo 2), el acoplamiento y la ley de Conway (Capítulo 3), y el cuanto de arquitectura, el monolito modular y los contextos delimitados (Capítulo 5). Quienes empiezan pueden leer primero el resumen inicial de cada sección y los recuadros "Si eres nuevo en esto". Los ingenieros con experiencia encontrarán precisión donde importa: lo que la entrega al menos una vez (at-least-once) implica para cada consumidor, lo que "exactamente una vez" significa y lo que no, y por qué la consistencia eventual debe diseñarse en lugar de tolerarse.

Qué llevarte

Tres hábitos recorren todas las secciones. Primero, cuenta las dependencias síncronas, no los servicios: el número de cosas que deben funcionar todas en el mismo momento para que la solicitud de un usuario tenga éxito decide la disponibilidad y la latencia. Segundo, da por hecho que los mensajes se pierden, se retrasan, se duplican y llegan desordenados, y diseña los receptores para que sean idempotentes. Tercero, decide quién es el propietario de cada dato, porque la propiedad decide dónde son posibles las transacciones y dónde hay que gestionar la consistencia entre servicios. El Capítulo 7 desarrolla ese tercer hábito en un tratamiento completo de la arquitectura de datos.

Las 8 secciones

6.1 · Intermedio · 24 minPor qué distribuirLas razones reales para repartir un sistema entre varias máquinas, las ocho falacias que hacen la distribución más difícil de lo que parece, el fallo parcial, los costos y la aritmética de las cadenas de llamadas síncronas.Leer →6.2 · Intermedio · 22 minBasada en servicios y SOAServicios de dominio de grano grueso que comparten una base de datos, la época del bus de servicios empresarial en SOA y por qué se desvaneció, en qué se diferencian los microservicios, y cuándo la arquitectura basada en servicios es el término medio pragmático.Leer →6.3 · Avanzado · 26 minMicroserviciosQué son los microservicios según Lewis y Fowler, los contextos delimitados, la desplegabilidad independiente, la base de datos por servicio, los gateways y las mallas, cómo decidir la granularidad, los antipatrones clásicos y el precio organizativo.Leer →6.4 · Avanzado · 28 minDirigida por eventosEventos, comandos y mensajes; las topologías de intermediario (broker) y de mediador; los cuatro patrones de eventos de Fowler; cómo funcionan las particiones, los offsets y los grupos de consumidores de Kafka; las garantías de entrega, los consumidores idempotentes, los esquemas y las colas de mensajes fallidos (dead-letter queues).Leer →6.5 · Intermedio · 30 minComunicación y APICómo se comunican los servicios: el acoplamiento que crean la comunicación síncrona y la asíncrona, REST y la semántica de HTTP, gRPC, GraphQL y la mensajería, y las prácticas de diseño de API que permiten que las interfaces evolucionen sin romper a los consumidores.Leer →6.6 · Avanzado · 30 minCAP y consistenciaQué significa la consistencia para los datos replicados: los modelos, de linealizable a eventual, lo que dice realmente el teorema CAP y lo que no dice, el compromiso cotidiano de latencia de PACELC, la aritmética de los quórums y cómo elegir la consistencia para cada caso de uso.Leer →6.7 · Avanzado · 30 minSagasCómo mantener la consistencia de los datos cuando una acción de negocio abarca varios servicios: la confirmación en dos fases y por qué se evita, las sagas con compensaciones, la coreografía y la orquestación, las contramedidas de aislamiento, la bandeja de salida transaccional (transactional outbox) y los receptores idempotentes.Leer →6.8 · Intermedio · 28 minServerless y basada en espaciosDos respuestas opuestas a la capacidad: las funciones serverless y los backends gestionados que escalan a cero y se facturan por uso, y la arquitectura basada en espacios, que atiende picos extremos desde memoria replicada con la base de datos fuera de la ruta crítica.Leer →

Prueba del capítulo

Comprueba lo que has entendido del capítulo 6

Opcional: 20 preguntas de opción múltiple y 2 respuestas escritas breves, elegidas de nuevo cada vez de un banco de 72 preguntas. Nota de aprobado: 80%. Superar todas las pruebas de capítulo y después la evaluación final da derecho al Certificado de Finalización Be Wise.

Haz la prueba del capítulo 6 en la app

Lecturas recomendadas