Be Software Architecture Wise
Be Wise Apps

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

Sección 6.1 de 6.8 · Intermedio · 24 min de lectura

Por qué distribuir y las falacias de la computación distribuida

Videolección

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

Repartir un sistema entre muchas máquinas aporta beneficios reales, y problemas que no pueden darse dentro de un solo programa. En esta lección aprenderás cuándo merece la pena, y cómo ponerle precio antes de pagarlo.

Imagina un pequeño restaurante en el que un solo cocinero lo hace todo en una sola cocina. Es sencillo. Si el cocinero se pone enfermo, el restaurante cierra, pero nada se pierde entre personas. Ahora imagina una cadena, con una panadería central, una cocina de salsas y muchas sucursales, todas unidas por furgonetas de reparto. Puede atender a muchos más clientes, y una cocina puede cerrar sin que cierren las demás. Pero las furgonetas se quedan atascadas en el tráfico y los pedidos se pierden. Cuando una entrega no llega, nadie sabe si la panadería nunca recibió el pedido o si se averió la furgoneta. El software distribuido funciona como la cadena.

Un sistema distribuido es un conjunto de programas en máquinas distintas que cooperan, enviándose mensajes a través de una red, para ofrecer lo que los usuarios ven como un único servicio. Una app de reparto de comida es uno. La idea clave de esta sección es que distribuir es una decisión con un precio, no una señal de madurez.

Hay unas pocas buenas razones para dividir un sistema. La primera es la escala: el flujo de ubicaciones de los repartidores recibe miles de actualizaciones por segundo; las pantallas de alta de restaurantes, unas pocas por hora. La segunda es el aislamiento de fallos. Una fuga de memoria en las recomendaciones no puede tumbar el proceso de pago, porque se ejecutan en máquinas distintas. Después, los lanzamientos independientes y la autonomía de los equipos. Estas razones organizativas suelen ser las de más peso. Otras son la geografía y la residencia de datos, las necesidades tecnológicas especiales y el aislamiento de seguridad, como mantener los datos de tarjetas en un servicio pequeño y reforzado. Pero cada una tiene un sustituto parcial más barato dentro de un monolito, como más copias detrás de un balanceador de carga, o cachés. Comprueba primero el sustituto.

El problema definitorio es el fallo parcial: algunas partes funcionan mientras otras han fallado, están lentas o no se pueden alcanzar. Aquí el servicio de pedidos pide al servicio de pagos que autorice veinticuatro libras con cincuenta, y espera. Si no llega respuesta antes del timeout, quizá la solicitud se perdió y no se hizo ningún cargo. Quizá el servicio de pagos se cayó o se bloqueó, y nadie sabe si se cargó la tarjeta. O quizá la tarjeta recibió el cargo y solo se perdió la respuesta. Para quien llama, las tres parecen idénticas. Así que toda operación que pueda reintentarse debe ser idempotente: hacerla dos veces tiene el mismo efecto que hacerla una. Normalmente cada solicitud lleva una clave única que el receptor recuerda.

Unos ingenieros de Sun Microsystems enumeraron ocho suposiciones falsas que hacen los recién llegados. Las dos primeras son que la red es fiable y que la latencia es cero. Así que pon un timeout en toda llamada remota, y prefiere unas pocas llamadas de grano grueso a muchas pequeñas. El ancho de banda no es infinito, y el transporte no es gratis. Envía solo los campos que necesitan los consumidores. La red no es segura, ni siquiera dentro de tu centro de datos. Autentica cada llamada entre servicios. La topología cambia, así que usa descubrimiento de servicios, no direcciones escritas a fuego. Y hay más de un administrador: un socio puede cambiar una regla y romper tus llamadas. Por último, la red no es homogénea, así que usa formatos estándar y versionados. Cada una de ellas sigue causando caídas reales.

Toda razón para distribuir se paga con la misma moneda. Primero, la latencia. Una llamada dentro de un proceso tarda nanosegundos. Un viaje de ida y vuelta entre máquinas de un mismo centro de datos tarda desde unos cientos de microsegundos hasta un milisegundo o más. Segundo, la observabilidad. La historia de una solicitud está repartida entre muchos logs, así que necesitas identificadores de correlación y trazado distribuido. Tercero, la consistencia. Con bases de datos separadas no hay una transacción compartida, así que los datos no coincidirán durante un tiempo y deben converger. Cuarto, y el más subestimado, la carga operativa. Cada servicio necesita un pipeline, monitorización y alguien de guardia. Estos costos crecen con el número de unidades desplegables.

Puedes ponerle precio a parte de esto sobre el papel. Aquí, hacer un pedido pasa por una cadena síncrona de cinco servicios. Cada uno espera al 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 solo un noventa y nueve punto cinco 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 unos dos por salto, la mediana es de unos ciento diez milisegundos. Esta dependencia de que la otra parte esté disponible en el mismo momento se llama acoplamiento temporal. Así que cuenta los saltos síncronos, no los servicios. Llama en paralelo a los servicios independientes, cachea los datos estables y deja que las partes que no necesitan responder de inmediato trabajen a partir de una cola.

La sección completa incluye las tablas completas y una lista de comprobación para usar antes de distribuir. A continuación, en la sección seis punto dos, veremos la arquitectura basada en servicios y la clásica arquitectura orientada a servicios. Nos vemos allí.

Lo que necesitas saber

Qué hace que un sistema sea distribuido

Un sistema distribuido es un conjunto de programas que se ejecutan en computadoras distintas y cooperan, enviándose mensajes a través de una red, para ofrecer lo que los usuarios ven como un único servicio. Tu app de reparto de comida es uno: el teléfono, los servicios de pedidos y de pagos de la empresa, la tableta del restaurante, el teléfono del repartidor y un procesador de tarjetas participan todos en un mismo pedido. El Capítulo 5 describió estilos que se despliegan como una sola unidad (monolitos); este capítulo trata de estilos cuyas partes se despliegan por separado y se comunican a través de la red.

Leslie Lamport, que hizo más que nadie por dar al campo una base matemática, resumió su dificultad esencial en un correo electrónico interno de mayo de 1987: un sistema distribuido es aquel en el que el fallo de una computadora cuya existencia ni siquiera conocías puede dejar inutilizable tu propia computadora. La broma funciona porque es verdad. En cuanto un sistema depende de máquinas que no controla y no puede ver, aparece toda una clase de fallos que simplemente no pueden ocurrir dentro de un solo proceso.

Por eso distribuir es una decisión con un precio, no una señal de madurez. El resto de esta sección expone las razones que justifican el precio, las suposiciones falsas que llevan a subestimarlo y una forma de calcular parte de él antes de pagarlo.

Por qué distribuir

Hay unas pocas razones legítimas para repartir un sistema entre procesos y máquinas. Cada una es un atributo de calidad del Capítulo 2 que a una sola unidad de despliegue le cuesta ofrecer a partir de cierto tamaño. Cada una tiene además un sustituto parcial más barato dentro de un monolito, y un buen arquitecto comprueba primero el sustituto.

Razones para distribuir y lo que ya puede hacer un monolito bien construido

RazónLo que ofrece la distribuciónLo que ya puede hacer un único despliegue
EscalaLas partes con cargas muy distintas pueden escalarse por separado: el flujo de ubicaciones de los repartidores recibe miles de actualizaciones por segundo; las pantallas de alta de restaurantes, unas pocas por hora.Ejecutar muchas réplicas idénticas detrás de un balanceador de carga y añadir réplicas de lectura y cachés. Esto basta para la mayoría de los sistemas y es mucho más barato.
Aislamiento de fallosUna fuga de memoria en las recomendaciones no puede tumbar el proceso de pago, porque se ejecutan en procesos distintos en máquinas distintas.Los pools de hilos separados y los bulkheads dentro de un mismo proceso dan un aislamiento parcial; un fallo grave sigue tumbándolo todo.
Desplegabilidad independienteUn equipo puede lanzar su parte veinte veces al día sin coordinar un lanzamiento con nadie más.Un monolito modular con buena automatización también puede lanzar muchas veces al día, pero cada lanzamiento lo entrega todo.
Autonomía de los equiposLos equipos son propietarios de un servicio de principio a fin, eligen su ritmo y están de guardia para él; la ley de Conway juega a tu favor en lugar de en tu contra.La propiedad por módulos funciona bien hasta unos pocos equipos; más allá, una compilación y un lanzamiento compartidos se convierten en una cola.
Geografía y residencia de datosEjecutar partes cerca de los usuarios para reducir la latencia, o mantener los datos personales en una jurisdicción porque lo exige una ley o un contrato.Desplegar una copia completa por región (una célula). Eso ya es en sí una forma de distribución, pero sencilla.
Distintas necesidades tecnológicasUn modelo de recomendación necesita GPU, la búsqueda necesita un motor de búsqueda y una integración heredada necesita un entorno de ejecución concreto.Llamar al componente especializado y mantener todo lo demás junto.
Aislamiento de seguridadQue los datos de tarjetas los gestione un servicio pequeño, reforzado y auditado por separado reduce el alcance de una evaluación PCI DSS.En realidad no: cualquier cosa dentro del proceso puede alcanzar cualquier otra en memoria.

De la tabla se desprenden dos observaciones. Primera, las razones de más peso suelen ser organizativas: la desplegabilidad independiente y la autonomía de los equipos importan sobre todo cuando muchos equipos trabajan en un mismo producto, y por eso la ley de Conway (Capítulo 3) reaparece una y otra vez en este capítulo. Segunda, la distribución rara vez es todo o nada. Muchos sistemas de éxito son un monolito modular más dos o tres servicios separados, cada uno desgajado por una razón concreta y explícita.

Fallo parcial: el problema definitorio

Dentro de un proceso, una llamada a una función o bien devuelve un resultado o bien todo el proceso muere con ella. A través de una red hay un tercer resultado, y lo cambia todo: el fallo parcial, en el que algunas partes del sistema funcionan mientras otras han fallado, están lentas o no se pueden alcanzar. Peor aún, a menudo quien llama no puede saber cuál es el caso.

Piensa en el servicio de pedidos pidiendo al servicio de pagos que autorice £24.50. Si no llega respuesta antes del timeout, el servicio de pedidos no sabe si la solicitud se perdió por el camino, si el servicio de pagos se cayó o se bloqueó antes o después de cargar la tarjeta, o si la tarjeta recibió el cargo y solo se perdió la respuesta. Las tres situaciones parecen idénticas desde el lado de quien llama.

Tres fallos que parecen el mismo

Quien llama envía una solicitud de pago; la solicitud puede perderse, el servidor puede caerse o bloquearse, o puede perderse la respuesta, y quien llama no sabe cuálServ. pedidos(quien llama)Servicio de pagos(destinatario)solicitud: autorizar £24.50resp.: aprobado1231 Solicitudperdida: sin cargo2 Destino caído o bloqueadocargo incierto3 Respuestaperdida: hubo cargoPara quien llama, las tres son idénticas: sin respuesta antes del timeout.
Tras un timeout, quien llama no puede saber si el trabajo se hizo; solo los reintentos idempotentes o una consulta posterior del estado pueden resolverlo.

Las consecuencias prácticas determinan todo diseño distribuido. Un reintento podría cobrar dos veces al cliente, así que las operaciones que pueden reintentarse deben hacerse seguras de repetir: esta propiedad es la idempotencia, y normalmente se consigue dando a cada solicitud una clave única que el receptor recuerda. Una dependencia lenta suele ser peor que una caída, porque quienes la llaman siguen esperando y acaparan hilos y conexiones; cuando un servicio se ralentiza, sus llamadores se quedan sin recursos y se ralentizan a su vez, lo que es un fallo en cascada. Y como una red puede dividirse de modo que dos grupos de máquinas no puedan alcanzarse entre sí mientras ambos siguen funcionando, los datos guardados en los dos sitios pueden divergir: el tema de la sección sobre CAP, más adelante en este capítulo.

Tampoco hay un reloj global. El reloj de cada máquina se desvía y se corrige por separado, de modo que las marcas de tiempo de dos servicios no pueden compararse con total confianza, y "¿qué pasó primero?" puede ser una pregunta difícil. El artículo de Lamport de 1978 sobre el tiempo y los relojes en los sistemas distribuidos mostró cómo ordenar eventos sin depender de relojes físicos; para los arquitectos, la lección es simplemente no basar la corrección en comparar horas de reloj entre máquinas.

Las ocho falacias de la computación distribuida

Las falacias de la computación distribuida son ocho suposiciones que hacen quienes se inician en los sistemas distribuidos, todas falsas y todas causantes de problemas tarde o temprano. La lista surgió en Sun Microsystems: L Peter Deutsch redactó siete en 1994, a partir de cuatro que ya habían señalado colegas como Bill Joy, y James Gosling, el creador de Java, añadió la octava hacia 1997. Tres décadas después, cada punto sigue describiendo una caída real en algún lugar esta misma semana.

Las ocho falacias, con una consecuencia y una respuesta de diseño para cada una

FalaciaQué sale mal si te la creesQué hacer en su lugar
1. La red es fiableUna llamada de pago se queda colgada; el hilo que llama espera eternamente; con carga, pronto todos los hilos están esperando y el servicio de pedidos deja de responder a nadie.Poner un timeout en toda llamada remota, reintentar solo operaciones idempotentes y poner colas donde el trabajo pueda esperar (patrones de resiliencia).
2. La latencia es ceroUna página del carrito que hacía 40 llamadas dentro del proceso ahora hace 40 llamadas de red de 2 ms cada una; aparecen 80 ms de la nada, y muchos más en la cola.Diseñar interfaces de grano grueso, agrupar solicitudes en lotes, llamar en paralelo a los servicios independientes y cachear los datos estables.
3. El ancho de banda es infinitoCada evento MenuUpdated lleva todas las fotografías de los platos; una noche de mucho trabajo satura el enlace y retrasa las actualizaciones de ubicación que lo comparten.Enviar identificadores y los campos que necesitan los consumidores, paginar, comprimir y mantener los datos masivos junto al código que los procesa.
4. La red es seguraLos servicios dentro del centro de datos aceptan cualquier solicitud sin autenticación; un solo contenedor comprometido puede llamar a la API de reembolsos.Cifrar y autenticar el tráfico entre servicios (por ejemplo, con TLS mutuo) y autorizar cada llamada: zero trust.
5. La topología no cambiaUna dirección IP escrita a fuego en la configuración deja de funcionar cuando el contenedor se reprograma en otra máquina.Usar descubrimiento de servicios y nombres DNS, y contar con que las instancias aparezcan y desaparezcan a cada minuto.
6. Hay un solo administradorUn proveedor de nube, el equipo de firewall de un socio u otro departamento cambia una regla, rota un certificado o baja un límite de tasa, y tus llamadas empiezan a fallar.Saber quién controla cada salto, monitorizar las dependencias que no son tuyas y acordar contratos y avisos de cambio.
7. El costo del transporte es ceroLa serialización consume CPU, y los datos que cruzan zonas de disponibilidad, regiones o la internet pública se facturan por gigabyte; la factura de red crece más rápido que el tráfico.Medir el costo de los flujos de datos, mantener local el tráfico muy conversacional y elegir formatos compactos donde el volumen es alto.
8. La red es homogéneaUn servicio supone que todos los clientes hablan la misma versión del protocolo, la misma codificación de caracteres y el mismo reloj; una red móvil, un sistema antiguo de un socio o un proxy rompe esa suposición.Usar formatos y protocolos estándar con versiones explícitas, y probar la interoperabilidad con los clientes reales.

Lo que cuesta distribuir

Toda razón para distribuir se paga con la misma moneda. La latencia es el primer costo. Una llamada a una función dentro de un proceso tarda nanosegundos; un viaje de ida y vuelta por la red entre máquinas del mismo centro de datos suele tardar desde unos cientos de microsegundos hasta un milisegundo o más, antes de cualquier serialización o trabajo. Entre continentes, la física pone el límite inferior: la luz en la fibra óptica viaja a unos 200 000 km por segundo, así que un viaje de ida y vuelta entre Londres y Nueva York (unos 5600 km en cada sentido) no puede tardar menos de unos 56 ms. La aritmética de la latencia de cola del Capítulo 2 se aplica a cada salto.

La observabilidad es el segundo. En un monolito, una traza de pila (stack trace) cuenta toda la historia de una solicitud fallida. En un sistema distribuido, la historia está repartida entre los logs de muchos servicios en muchas máquinas. La observabilidad, la capacidad de entender lo que está haciendo el sistema a partir de sus salidas, tiene que diseñarse desde el principio: identificadores de correlación transmitidos en cada llamada, logs centralizados, métricas por servicio y trazado distribuido (Capítulo 9).

La consistencia es el tercero. Una sola transacción de base de datos puede actualizar un pedido y su pago de forma atómica. Cuando el pedido y el pago viven en servicios distintos con bases de datos distintas, no hay una transacción compartida; el sistema debe aceptar un periodo en el que los dos no coinciden y debe asegurarse de que converjan. Las secciones posteriores tratan las herramientas: los modelos de consistencia y las sagas y el patrón outbox.

La carga operativa es el cuarto, y el que más a menudo se subestima. Cada servicio necesita un pipeline de compilación, un despliegue, configuración, secretos, monitorización, alertas, planificación de capacidad, parches de seguridad y alguien de guardia. Las pruebas también cambian: un cambio solo es seguro si todos los consumidores de su interfaz siguen funcionando, lo que exige pruebas de contrato y cambios compatibles hacia atrás. Estos costos son aproximadamente proporcionales al número de unidades desplegables, y por eso importa el número de servicios.

Hacer las cuentas: las cadenas síncronas

El momento más barato para descubrir que un diseño distribuido es demasiado frágil o demasiado lento es sobre el papel. La herramienta es la regla de los componentes en serie del Capítulo 2: si una solicitud necesita que funcionen todos los componentes de una cadena, la disponibilidad de la cadena es el producto de las disponibilidades de los componentes, y su latencia es aproximadamente la suma de las suyas.

Una cadena síncrona de cinco servicios

Una solicitud de un cliente pasa por cinco servicios en una cadena síncrona, cada uno disponible al 99.9 por ciento con una mediana de 20 milisegundos; la disponibilidad de la cadena es el producto y su latencia, la sumaApp clienteAPI gateway99.9%mediana 20 msPedidos99.9%mediana 20 msCarta99.9%mediana 20 msPrecios99.9%mediana 20 msPagos99.9%mediana 20 mscada llamada espera a que responda la siguienteDisponib. se multiplica0.999⁵ ≈ 99.50%: unas 3.6 h de inactividad al mesLatencia: suma5 × (20 ms + 2 ms por salto) ≈ 110 ms de mediana
Cinco servicios que cumplen cada uno el 99.9% producen una ruta de solicitud que solo cumple alrededor del 99.5%, y con cinco veces la latencia de uno.

Ejemplo práctico

Ejemplo práctico: el presupuesto de disponibilidad y de latencia de una cadena de llamadas

Una plataforma de reparto de comida gestiona Hacer pedido con una cadena síncrona: el API gateway llama al servicio de pedidos, que llama al servicio de carta, que llama al de precios, que llama al de pagos. Cada servicio por sí solo cumple una disponibilidad del 99.9% (medida en tiempo, sobre un mes de 30 días de 43 200 minutos), responde con una mediana de 20 ms de trabajo propio y tiene un p99 de 250 ms. Cada salto de red añade unos 2 ms. Supón, con generosidad, que los fallos son independientes y que cualquier fallo hace fallar toda la solicitud.

Un servicioDisponibilidad 0.999 = 99.9%; inactividad permitida 0.001 × 43 200 = 43.2 minutos al mes.
Dos en serie0.999 × 0.999 = 0.998 (99.8%); unos 86 minutos al mes.
Cinco en serie0.9995 ≈ 0.99501 (99.50%); no disponible unos 0.005 × 43 200 ≈ 216 minutos, o 3.6 horas, al mes. Cinco servicios respetables por separado han producido un sistema de dos nueves y medio.
Diez en serie0.99910 ≈ 0.99004 (99.0%); unos 430 minutos, más de 7 horas, al mes.
Latencia mediana, cinco en serieLas latencias se suman: aproximadamente 5 × (20 ms + 2 ms) ≈ 110 ms, frente a 20 ms para el mismo trabajo hecho en un solo proceso. (En sentido estricto, las medianas no se suman exactamente; la suma es una buena primera estimación.)
Latencia de cola, cinco en serieLa probabilidad de que una solicitud se encuentre al menos un salto en su 1% más lento es 1 − 0.995 ≈ 4.9%, así que alrededor de 1 solicitud de cada 20 se ve ralentizada por al menos un salto de 250 ms. Con diez saltos es 1 − 0.9910 ≈ 9.6%.
Lo que hace falta para mantener el 99.9% de extremo a extremoCada uno de los cinco servicios necesitaría alrededor del 99.98% (0.99985 ≈ 0.9990): unos 8.6 minutos de inactividad al mes cada uno, lo que en la práctica significa recuperación automatizada.
Respuestas de diseñoLlamar a carta y a precios en paralelo (la latencia pasa a ser la del más lento de los dos, no la suma); cachear los datos de la carta en el servicio de pedidos; hacer asíncrona la confirmación del pago para que el pedido se acepte y se pague poco después; eliminar los saltos que solo reenvían solicitudes.

El Capítulo 2 presentó la regla de que las disponibilidades se multiplican en serie; la distribución es donde esa regla empieza a doler, porque cada llamada de red añade un componente a la serie.

La suposición de independencia embellece el resultado. Los servicios que comparten una base de datos, un clúster, un sistema de configuración o un tren de lanzamientos fallan juntos, y un destinatario lento puede agotar los hilos de quien lo llama y propagar la caída hacia arriba.

La solución rara vez es hacer cada servicio heroicamente fiable. Consiste en acortar las cadenas síncronas y dejar que las partes que no necesitan responder de inmediato trabajen a partir de una cola.

El cuanto de arquitectura, de nuevo

El Capítulo 5 presentó el cuanto de arquitectura: una parte desplegable de forma independiente, con alta cohesión funcional e incluidos sus datos, a la que se aplica un único conjunto de características de arquitectura (Estilos, patrones y tácticas arquitectónicos). En Software Architecture: The Hard Parts (2021), Ford, Richards, Sadalage y Dehghani afinan la idea con dos tipos de acoplamiento. El acoplamiento estático es lo que debe estar presente para que una parte se despliegue y se ejecute: su código, sus bibliotecas, su base de datos y su infraestructura. El acoplamiento dinámico es cómo dependen las partes unas de otras durante la ejecución: si se llaman de forma síncrona o asíncrona, y cómo se coordinan y se mantienen consistentes.

El ejemplo práctico muestra por qué importa el lado dinámico. Mientras dura una llamada síncrona, quien llama no puede completar su trabajo a menos que el destinatario esté disponible y responda rápido; los dos quedan unidos operativamente, y su disponibilidad y su latencia se combinan como se calculó más arriba. Cinco servicios desplegados por separado en una cadena síncrona son cinco unidades de despliegue, pero para la disponibilidad de Hacer pedido se comportan como una sola unidad frágil. Esta dependencia de que la otra parte esté disponible en el mismo momento es el acoplamiento temporal. La mensajería asíncrona elimina gran parte de él: si el servicio de pedidos deja un mensaje en una cola duradera, el servicio de pagos puede estar caído un minuto y ponerse al día después, y el cliente sigue recibiendo un número de pedido. El costo es que el cliente no recibe de inmediato una respuesta definitiva, lo que es tanto una decisión de producto como técnica.

Esta es la lección más profunda de la sección. Trazar los límites de los servicios es la mitad del diseño; decidir qué interacciones deben ser síncronas, y mantener pequeño ese conjunto, es la otra mitad.

Lista de comprobación: antes de distribuir

Usa estas preguntas antes de repartir un sistema, o una parte de él, a través de la red.

  • Nombra el impulsor¿Qué razón de la tabla anterior se aplica, a qué parte y con qué evidencia? "Los microservicios son modernos" no es un impulsor.
  • Prueba primero la solución más barata¿Podrían cubrir la necesidad unas réplicas, una caché, una réplica de lectura, un proceso en segundo plano o un límite de módulo más claro dentro del monolito?
  • Dibuja el grafo de llamadasCuenta los saltos síncronos de cada recorrido clave del usuario y calcula el presupuesto de disponibilidad y de latencia, como en el ejemplo práctico.
  • Decide quién es el propietario de qué datosCada dato necesita un único servicio propietario; todo lo que deba cambiar de forma atómica con él probablemente pertenezca al mismo servicio.
  • Diseña para el fallo parcialTimeouts, reintentos con idempotencia, alternativas (fallbacks) y lo que ve el usuario cuando una dependencia está caída, decididos antes de la primera caída.
  • Comprueba los requisitos previosEl aprovisionamiento y el despliegue automatizados, la monitorización, los logs centralizados y el trazado distribuido deben existir, o estar planificados y financiados.
  • Ajusta los equipos a los límitesCada servicio debe tener un único equipo propietario que pueda cambiarlo, desplegarlo y darle soporte sin pedir permiso a otros.

Comprueba lo que has entendido

Un servicio llama a un servicio de inventario sin timeout. El servicio de inventario se vuelve muy lento en lugar de fallar. ¿Por qué puede ser esto peor que si se hubiera caído?

Un servicio caído falla rápido y quienes lo llaman pueden reaccionar; uno lento los mantiene esperando, de modo que sus hilos y conexiones se llenan hasta que también dejan de responder, y la caída se propaga como un fallo en cascada.

Tres servicios tienen cada uno una disponibilidad del 99.95% y se llaman en serie en cada solicitud. ¿Cuál es la disponibilidad aproximada de la ruta de solicitud?

0.99953 ≈ 0.9985, alrededor del 99.85%, suponiendo fallos independientes.

¿Por qué importa la falacia "el costo del transporte es cero" aunque la latencia y el ancho de banda estén bien?

Mover datos cuesta CPU para la serialización y dinero por el tráfico entre zonas, regiones o proveedores, así que un diseño muy conversacional o voluminoso puede salir caro aunque sea lo bastante rápido.

¿Por qué cinco servicios desplegados por separado pueden comportarse aún como una sola unidad a efectos de disponibilidad?

Si una solicitud los llama de forma síncrona en cadena, los cinco deben estar disponibles en el mismo momento; sus disponibilidades se combinan, de modo que están acoplados temporalmente pese a desplegarse por separado.

Siguiente · 6.2Basada 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.Continuar →

Fuentes y lecturas recomendadas

¿Tienes una pregunta sobre esta sección? ArchitectBot, el asistente de estudio con IA del curso, responde primero a partir del curso.

Pregunta: “Nuestro proceso de pago llama a seis servicios uno tras otro. ¿Cómo averiguo si eso es demasiado frágil y qué deberíamos cambiar primero?”