Sistemas distribuidos. Patrones de diseño. Reseña del libro

Hola colegas Hoy publicamos una traducción de la próxima reseña del sitio de Ben Neidel: este sitio seguramente le interesará en el original. Esta vez hablaremos del libro " Sistemas distribuidos. Patrones de diseño ", que complementa el libro " Master Kubernetes " que se publicó a principios de este año y, en esencia, es un análogo de GoF para el diseño de sistemas distribuidos.



Que tengas una buena lectura.

Durante el fin de semana, leí el libro Sistemas distribuidos. Patrones de diseño, por Brendan Burns . Realmente me gustó el libro, aunque, debo admitirlo, esperaba encontrar un poco de material diferente en él. Entonces, en la descripción de los contenedores de libros se mencionan solo de pasada. Al mismo tiempo, aunque los patrones descritos en el libro son aplicables no solo para la contenedorización, casi todos los patrones descritos aquí se dan en el contexto del contenedor, y después de eso se consideran en la tubería de implementación de Kubernetes. Resultó por cierto. Estoy empezando a familiarizarme con el desarrollo y la implementación orientados a contenedores, y discutir los patrones arquitectónicos desde un punto de vista de "contenedor" fue una revelación para mí. Este enfoque me ayudó a comprender bien cómo en el panorama de microservicios se distinguen correctamente los pequeños servicios, cada uno de los cuales tiene una oportunidad específica.

El autor del libro, Brendan Burns, es el cofundador del proyecto de código abierto Kubernetes. Por lo tanto, no es sorprendente que todos sus ejemplos de aplicaciones se construyan alrededor de la implementación de contenedores basados ​​en archivos de configuración de Kubernetes. En el momento de leer el libro, estaba un poco versado en Docker y no sabía nada sobre Kubernetes. Por lo tanto, traté de averiguar el "propósito" de los archivos de configuración de Kubernetes simplemente leyéndolos. Sin embargo, creo que el libro será más útil si el lector tiene al menos algo de experiencia con Kubernetes.

Al leer el libro, no pude deshacerme de las asociaciones con el trabajo " Plantillas de integración para aplicaciones empresariales " de Gregor Hope y Bobby Wolf. Muchos de los patrones discutidos por Burns son muy similares a los patrones de cola de mensajes discutidos por Hope y Wolfe. De hecho, debo decir que muchos patrones incluso se mencionan en ambos libros de la misma manera (por ejemplo, Scatter / Gather). Esto es lógico, ya que el tema de ambos libros es la partición de sistemas monolíticos complejos en un conjunto de servicios reutilizables pequeños y ajustados. Creo que incluso se puede argumentar que Burns establece enfoques específicos que serán útiles para implementar los servicios Productor y los Servicios al consumidor involucrados en el funcionamiento de los flujos de trabajo basados ​​en mensajes, los mismos que se describen en el libro "Plantillas de integración de aplicaciones empresariales".

Nuevamente, creo que los paralelos trazados entre estos dos libros dan testimonio del poder de los patrones de diseño. Tanto en lo bien que nos llevan a soluciones probadas, como en el hecho de que los patrones de diseño facilitan la comunicación técnica, ya que nos permiten razonar en un lenguaje común.

Al mismo tiempo, uno de los enfoques que más me gustó se describe en el libro "Sistemas distribuidos. Patrones de diseño ”está relacionado precisamente con el consumo de la cola de mensajes. Burns aconseja no forzar al contenedor de trabajo a extraer mensajes directamente del sistema (de forma similar a como se hace en el sistema Simple Queue Service (SQS) de Amazon), sino crear un "embajador" (patrón de embajador). Dicho contenedor de "embajador" se desplegará junto con el contenedor de trabajo y proporcionará una API generalizada para manipular las colas. El contenedor Ambassador le permite abstraer detalles de implementación relacionados con el almacenamiento permanente de elementos en la cola de mensajes, de modo que el contenedor de trabajo sea completamente independiente de cualquier solución tecnológica específica.

“El embajador de la fuente del contenedor de la cola de trabajo” es solo un ejemplo de un tema transversal que recorre el libro como un hilo rojo: use colecciones de contenedores pequeños para que cada contenedor individual pueda enfocarse en una tarea específica y ser lo más reutilizable posible. Burns explora este concepto a nivel de contenedor individual, hablando sobre la parametrización de contenedores utilizando argumentos de línea de comando y variables de entorno. Luego sube un nivel, habla sobre los modelos de vagones laterales y embajadores de contenedores múltiples en un contexto de nodo único. Finalmente, muestra cómo crear una poderosa arquitectura de microservicios utilizando patrones de contenedores múltiples.

Creo que Burns pudo articular perfectamente el "sueño" de todo el panorama de microservicios:

El enfoque de microservicio tiene muchas ventajas, muchas de las cuales están relacionadas con la fiabilidad y la flexibilidad. Los microservicios dividen la aplicación en partes pequeñas, cada una de las cuales es responsable de la prestación de un servicio específico. Al reducir el alcance de los servicios, cada servicio puede desarrollar y mantener un equipo que se puede alimentar con dos pizzas.

Reducir el tamaño del equipo también reduce el costo de mantener sus actividades.

Además, la aparición de una interfaz formal entre microservicios debilita la interdependencia de los equipos y establece un contrato confiable entre los servicios. Tal contrato formal reduce la necesidad de una estrecha sincronización de los equipos, ya que el equipo que proporciona la API comprende hasta qué punto es necesario para garantizar la compatibilidad, y el equipo que consume la API puede contar con un servicio estable sin preocuparse por los detalles de la implementación del servicio consumido. Dicha descomposición permite a los equipos controlar de forma independiente el ritmo de desarrollo y el cronograma para el lanzamiento de nuevas versiones, lo que les da la oportunidad de iterar, mejorando así el código de servicio.

Finalmente, dividir en microservicios aumenta la escalabilidad. Dado que cada componente se asigna a un servicio separado, se puede escalar independientemente de los demás

(p. 79-80 en traducción rusa)

Estoy hablando del "sueño" porque, como admite el propio Burns, es difícil diseñar un sistema de microservicio y diseñar su arquitectura. Y monitorear y depurar dicho sistema es mucho más complicado que monitorear y depurar un análogo monolítico. Solo con esto puedo estar de acuerdo fácilmente. De acuerdo con mi propia experiencia limitada trabajando con microservicios, confirmo que los servicios compartidos se conectan rápidamente y que los "contratos confiables" entre los servicios se convierten rápidamente en un objetivo móvil, experimentando más y más cambios nuevos.

En conclusión, me gustaría referirme al concepto de FaaS: "funciones como servicios". Sistemas como el servicio Lambda de Amazon me hacen sentir mezclado. En un sentido extremadamente abstracto, me gustan tales sistemas, pero no tengo idea de cómo se manifiestan en una aplicación particular. Burns toca FaaS en la Parte II sobre "Patrones de diseño de sistemas de servicio", pero desafortunadamente no me aclara completamente el problema de Faas.

Realmente me gustó que Burns recomienda usar FaaS para resolver solo un subconjunto de los problemas conocidos:

Al igual que con otras herramientas para desarrollar sistemas distribuidos, es posible que desee utilizar una solución particular (por ejemplo, procesamiento orientado a eventos) como herramienta universal. La verdad es que una solución particular generalmente resuelve problemas particulares. En cierto contexto, demostrará ser una herramienta poderosa, pero al tirar de ella para resolver problemas comunes se crean arquitecturas complejas y frágiles.

(p. 135 en traducción rusa)

Además, muchas gracias a él por mencionar las dificultades que surgen al usar FaaS:

Como se mencionó en la sección anterior, el desarrollo del sistema utilizando el enfoque FaaS lo obliga a hacer que los componentes del sistema se acoplen libremente. Cada función es independiente por definición. Toda la interacción se lleva a cabo a través de la red. Las instancias de función no tienen su propia memoria; por lo tanto, requieren almacenamiento compartido para almacenar el estado. El debilitamiento forzado de la conectividad de los elementos del sistema puede aumentar la flexibilidad y la velocidad del desarrollo del servicio, pero al mismo tiempo puede complicar significativamente su soporte.
En particular, es bastante difícil ver la estructura integral del servicio, determinar cómo se integran las funciones entre sí, comprender qué y por qué salió mal en caso de falla. Además, la naturaleza de las funciones orientada a consultas y sin servidor significa que algunos problemas serán difíciles de detectar.

(p. 136-137 en traducción rusa)

Nuevamente, me sorprendió el hecho de que la mayoría de los sistemas FaaS no son demasiado buenos para resolver tareas que requieren un procesamiento activo:

... además, debido a la implementación de servicios sin servidor, el tiempo de ejecución de una instancia de función generalmente es limitado. Esto significa que el enfoque FaaS generalmente no es adecuado para aplicaciones que requieren un procesamiento prolongado de datos en segundo plano. (P. 138 en traducción rusa)
Finalmente, me complació la observación de que los FaaS se están volviendo económicamente inexpertos si es imposible garantizar un funcionamiento prolongado e ininterrumpido del procesador:
Pero si tiene tantas solicitudes que la función está constantemente activa, es probable que pague de más por la cantidad de solicitudes procesadas.

... a medida que el servicio crece, el número de solicitudes procesadas aumenta a tal nivel que el procesador está constantemente ocupado procesándolas. En este punto, la tarifa por el número de solicitudes comienza a dejar de ser rentable. El costo por unidad de tiempo de CPU de las máquinas virtuales en la nube disminuye a medida que se agregan núcleos, así como al reservar recursos y descuentos para uso a largo plazo. El costo de pagar la cantidad de solicitudes generalmente aumenta con la cantidad de solicitudes.

(p. 139-140 en traducción rusa)

Como resultado, todavía no entendía: ¿cuándo es mejor usar "funciones como servicios"? Observo que Burns describe brevemente el trabajo con tareas a corto plazo orientadas a eventos que no cargan mucho el procesador, como la autenticación de dos factores (2FA). Sin embargo, dado que estamos hablando de pequeñas tareas a corto plazo con bajos costos, surge la pregunta: ¿por qué deberían escalarse independientemente? ¿Por qué no incluir estas características en otro servicio contenedor que está estrechamente relacionado con el primero?

Espero lidiar mejor con estos problemas cuando empiece a usar las tecnologías FaaS en la práctica.

Además de cierta confusión con FaaS, me gustó mucho el libro. Se lee rápidamente, fácilmente percibido. Una vez más nos recuerda el enorme potencial de debilitar la conexión entre componentes en todos los niveles de desarrollo de aplicaciones. Finalmente, ahora será mucho más fácil para mí mantener una conversación con mis colegas sobre temas como "Contenedores de sidecar".

Source: https://habr.com/ru/post/442514/


All Articles