Bloques de construcción de aplicaciones distribuidas. Aproximación cero

Bloques de construcción de aplicaciones distribuidas. Aproximación cero

El mundo no se detiene. El progreso crea nuevos desafíos tecnológicos. De acuerdo con los requisitos cambiantes, la arquitectura de los sistemas de información debe evolucionar. Hoy hablaremos sobre arquitectura basada en eventos, concurrencia, concurrencia, asincronía y cómo vivir pacíficamente con todo esto en Erlang.

introducción

Dependiendo del tamaño del sistema diseñado y de sus requisitos, nosotros, los desarrolladores, elegimos el método de intercambio de información en el sistema. En la mayoría de los casos, para organizar la interacción de servicios, una opción de trabajo puede ser un esquema con un corredor, por ejemplo, basado en RabbitMQ o Kafka. Pero a veces el flujo de eventos, el SLA y el nivel de control sobre el sistema son tales que la mensajería ya preparada no nos conviene. Por supuesto, puedes complicar un poco el sistema asumiendo la responsabilidad de la capa de transporte y la formación de clústeres, por ejemplo usando ZeroMQ o nanomsg. Pero si el sistema tiene suficiente rendimiento y capacidades de un clúster Erlang estándar, entonces la cuestión de introducir una entidad adicional requiere un estudio detallado y una justificación económica.

El tema de las aplicaciones distribuidas reactivas es bastante amplio. Para mantener el formato del artículo, el tema de discusión de hoy serán solo entornos homogéneos construidos en Erlang/Elixir. El ecosistema Erlang/OTP le permite implementar una arquitectura reactiva con la menor cantidad de esfuerzo. Pero en cualquier caso necesitaremos una capa de mensajería.

Bases teóricas

El diseño comienza con la definición de objetivos y limitaciones. El objetivo principal no es el desarrollo por el desarrollo. Necesitamos obtener una herramienta segura y escalable a partir de la cual podamos crear y, lo más importante, desarrollar aplicaciones modernas de varios niveles: comenzando desde aplicaciones de un solo servidor que atienden a una audiencia pequeña, que luego pueden convertirse en grupos de hasta 50 -60 nodos, finalizando con las federaciones de clusters. Por tanto, el objetivo principal es maximizar los beneficios reduciendo el coste de desarrollo y propiedad del sistema final.

Resaltemos 4 requisitos principales para el sistema final:

  • Сorientado a eventos.
    El sistema siempre está listo para atravesar el flujo de eventos y realizar las acciones necesarias;
  • Мescalabilidad.
    Los bloques individuales se pueden escalar tanto vertical como horizontalmente. Todo el sistema debe ser capaz de un crecimiento horizontal infinito;
  • ОTolerancia a fallos.
    Todos los niveles y todos los servicios deberían poder recuperarse automáticamente de los fallos;
  • ГTiempo de respuesta garantizado.
    El tiempo es valioso y los usuarios no deberían esperar demasiado.

¿Recuerdas el viejo cuento de hadas sobre “El pequeño motor que podía”? Para que el sistema diseñado salga exitosamente de la etapa de prototipo y sea progresivo, su base debe cumplir con los requisitos mínimos SMOG.

A la mensajería como herramienta de infraestructura y base de todos los servicios se le suma un punto más: la facilidad de uso para los programadores.

Orientado a eventos

Para que una aplicación crezca desde un único servidor hasta un clúster, su arquitectura debe admitir un acoplamiento flexible. El modelo asincrónico cumple este requisito. En él, el remitente y el destinatario se preocupan por la carga de información del mensaje y no se preocupan por la transmisión y el enrutamiento dentro del sistema.

Escalabilidad

La escalabilidad y la eficiencia del sistema están juntas. Los componentes de la aplicación deben poder utilizar todos los recursos disponibles. Cuanto más eficientemente podamos utilizar la capacidad y más óptimos sean nuestros métodos de procesamiento, menos dinero gastaremos en equipos.

Dentro de una sola máquina, Erlang crea un entorno altamente competitivo. El equilibrio entre concurrencia y paralelismo se puede establecer eligiendo la cantidad de subprocesos del sistema operativo disponibles para Erlang VM y la cantidad de programadores que utilizan estos subprocesos.
Los procesos de Erlang no comparten estado y operan en modo sin bloqueo. Esto proporciona una latencia relativamente baja y un mayor rendimiento que las aplicaciones tradicionales basadas en bloqueo. El programador de Erlang garantiza una asignación justa de CPU e IO, y la ausencia de bloqueo permite que la aplicación responda incluso durante cargas máximas o fallas.

A nivel de cluster, también existe el problema de la eliminación. Es importante que todas las máquinas del clúster estén cargadas de manera uniforme y que la red no esté sobrecargada. Imaginemos una situación: el tráfico de usuarios llega a los balanceadores entrantes (haproxy, nginx, etc.), que distribuyen las solicitudes de procesamiento de la manera más uniforme posible entre el conjunto de backends disponibles. Dentro de la infraestructura de la aplicación, el servicio que implementa la interfaz requerida es solo el último kilómetro y necesitará solicitar una serie de otros servicios para responder a la solicitud inicial. Las solicitudes internas también requieren enrutamiento y equilibrio.
Para gestionar eficazmente los flujos de datos, la mensajería debe proporcionar a los desarrolladores una interfaz para gestionar el enrutamiento y el equilibrio de carga. Gracias a esto, los desarrolladores podrán, utilizando patrones de microservicios (agregador, proxy, cadena, rama, etc.), resolver tanto problemas estándar como aquellos que rara vez surgen.

Desde un punto de vista empresarial, la escalabilidad es una de las herramientas de gestión de riesgos. Lo principal es satisfacer las solicitudes de los clientes utilizando de manera óptima el equipo:

  • Cuando la potencia de los equipos aumenta como resultado del progreso. No estará inactivo debido a un software imperfecto. Erlang escala bien verticalmente y siempre podrá utilizar todos los núcleos de CPU y la memoria disponible;
  • En entornos de nube podemos gestionar la cantidad de equipos en función de la carga actual o prevista y garantizar SLA.

Tolerancia a fallos

Consideremos dos axiomas: "Los fracasos son inaceptables" y "Siempre habrá fracasos". Para una empresa, una falla del software significa pérdida de dinero y, lo que es peor, pérdida de reputación. Al equilibrar las posibles pérdidas y el costo de desarrollar software tolerante a fallas, a menudo se puede encontrar un compromiso.

A corto plazo, una arquitectura que incorpora tolerancia a fallos ahorra dinero en la compra de soluciones de agrupación en clústeres disponibles en el mercado. Son caros y también tienen errores.
A largo plazo, una arquitectura tolerante a fallos se amortiza muchas veces en todas las etapas de desarrollo.
La mensajería dentro del código base le permite analizar en detalle la interacción de los componentes dentro del sistema en la etapa de desarrollo. Esto simplifica la tarea de responder y gestionar fallas, ya que todos los componentes críticos manejan las fallas y el sistema resultante sabe cómo volver automáticamente a la normalidad después de una falla por diseño.

Capacidad de respuesta

Independientemente de las fallas, la aplicación debe responder a las solicitudes y cumplir con el SLA. La realidad es que la gente no quiere esperar, por lo que las empresas deben adaptarse en consecuencia. Se espera que cada vez más aplicaciones tengan una gran capacidad de respuesta.
Las aplicaciones responsivas funcionan casi en tiempo real. Erlang VM opera en modo suave en tiempo real. Para algunas áreas, como el comercio de acciones, la medicina y el control de equipos industriales, el modo estricto en tiempo real es importante.
Los sistemas responsivos mejoran la UX y benefician al negocio.

Resultado preliminar

Al planificar este artículo, quería compartir mi experiencia en la creación de un corredor de mensajería y la construcción de sistemas complejos basados ​​en él. Pero la parte teórica y motivacional resultó bastante extensa.
En la segunda parte del artículo hablaré sobre los matices de la implementación de puntos de cambio, los patrones de mensajería y su aplicación.
En la tercera parte consideraremos cuestiones generales de organización de servicios, enrutamiento y equilibrio. Hablemos del lado práctico de la escalabilidad y la tolerancia a fallas de los sistemas.

El final de la primera parte.

Galleria @lucabravo.

Fuente: habr.com

Añadir un comentario