Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Arquitectura orientada a eventos en AWS, Parte I: lo básico

By Vlad KhononovDec 16, 20246 min read

Esta página también está disponible en English, Deutsch, Français, Italiano, 日本語 y Português.

La gran variedad de servicios que ofrece AWS muchas veces permite implementar una misma funcionalidad de distintas formas. En el caso de los sistemas de mensajería, AWS pone a disposición servicios como Simple Notification Service (SNS), Simple Queue Service (SQS), EventBridge, Kinesis y Managed Streaming for Apache Kafka (MSK). A primera vista podría parecer que al menos un subconjunto de estos servicios cumple la misma función. En este post quiero describir la arquitectura a la que siempre recurro y explicar por qué, en mi opinión, es la solución más simple, económica y robusta para la mayoría de los casos.

Arquitectura orientada a eventos

Los componentes de un sistema orientado a eventos se comunican publicando eventos y suscribiéndose a ellos. La integración asíncrona aporta ventajas no funcionales importantes. Por ejemplo, desacopla los ciclos de vida de los componentes integrados. Hasta cierto punto, el sistema puede seguir funcionando incluso si algunos de sus servicios no están disponibles, lo que también reduce la coordinación necesaria para desplegar componentes actualizados y para hacer evolucionar el sistema.

Una integración básica orientada a eventos consta de dos partes: un componente del sistema puede publicar eventos que describen sucesos importantes de su ciclo de vida, y puede reaccionar (suscribirse) a eventos publicados por otras partes del sistema. Veamos qué servicios administrados podemos aprovechar para implementarlo.

Publicación: SNS

AWS Simple Notification Service (SNS) es un servicio totalmente administrado que te permite enviar notificaciones para que otros componentes del sistema las consuman. Su naturaleza serverless y sus precios bajos convierten a SNS en un excelente candidato para publicar eventos. La Figura 1 muestra un servicio llamado "Producer" que publica sus eventos a través de un topic de SNS.

Figura 1: el servicio "Producer" publica eventos en un topic de SNS.

¿Y qué pasa con el servicio "Consumer" del lado derecho de la figura? ¿Cómo puede suscribirse a los mensajes publicados por el Producer?

SNS admite la entrega de mensajes a través de varios protocolos, como HTTP, la activación de funciones AWS Lambda, SMS y otros. En teoría, podría parecer razonable que el Consumer expusiera un endpoint HTTP y se usara como destino del topic de SNS, como se ilustra en la Figura 2.

Figura 2: un topic de SNS puede reenviar mensajes a endpoints HTTP. Pero ¿es la mejor solución?

¿De verdad es la mejor solución? Si asumimos que los dos servicios, Producer y Consumer, pertenecen a equipos distintos, ¿quién está a cargo del topic de SNS? El equipo del Producer tiene que asegurarse de que el topic esté bien configurado para recibir sus mensajes, mientras que los equipos a cargo de los servicios consumidores deben garantizar que los destinos sean siempre correctos. Una propiedad compartida así es una receta para la fricción. Veamos otra opción.

Suscripción: SQS

AWS SQS es una cola de eventos totalmente administrada que retiene temporalmente los mensajes (eventos) generados por los productores hasta que los consumidores los procesan. Permite el manejo distribuido de eventos con balanceo de carga entre varios consumidores, algo clave para mantener la tolerancia a fallos en flujos orientados a eventos. En mi opinión, también ofrece mucha mayor visibilidad sobre las colas que los topics de SNS, y un control cómodo sobre cómo se entregan los mensajes a los consumidores.

Como SQS es uno de los destinos compatibles con los topics de SNS, vamos a configurar una cola para los mensajes que procesarán los servicios "Consumer", como se muestra en la Figura 3.

Figura 3: uso de SQS como mecanismo de consumo de eventos.

Con esta configuración, los límites de propiedad quedan claros:

  • El topic de SNS que se usa para publicar mensajes pertenece al equipo a cargo del servicio originador (Producer).
  • La cola de SQS que se usa para consumir mensajes pertenece al equipo a cargo del servicio suscriptor (Consumer).

La separación de responsabilidades entre ambos servicios debe verse reflejada en la arquitectura del sistema.

SNS + SQS: una EDA simple

Es ampliamente aceptado que un microservicio debe permitir el acceso a sus datos a través de una interfaz pública bien definida, mientras que su base de datos se considera un detalle de implementación y debe ocultarse a los consumidores. Esta encapsulación estricta del mecanismo de persistencia permite definir límites de propiedad más claros, ganar flexibilidad para hacer evolucionar los microservicios y tener mucho más control sobre las interfaces públicas.

El bus de mensajes que utiliza el sistema no deja de ser otro mecanismo de persistencia —aunque mucho más limitado— y debe tratarse como tal. Por eso, además de una base de datos, cada (micro)servicio necesita un topic de SNS para publicar eventos y una cola de SQS para consumirlos, como se muestra en la Figura 4:

Figura 4: una EDA exige definir límites de propiedad claros no solo para las bases de datos, sino también para sus mecanismos de mensajería (SNS y SQS).

Las flechas entre los servicios —las suscripciones desde los topics hacia las colas— pertenecen a un nivel de abstracción arquitectónica superior al de los propios servicios. Por ejemplo, podría haber una plantilla de CloudFormation por cada servicio individual y una plantilla de CloudFormation de mayor nivel para el sistema resultante. Esta última se encarga de definir las suscripciones.

Vale la pena mencionar que una suscripción no implica que todos los eventos publicados se vuelquen ciegamente sobre los consumidores; una suscripción puede especificar un filtro para reenviar únicamente los eventos relevantes para cada consumidor.

Este enfoque está alineado con el principio de smart endpoints, dumb pipes, esencial para la simplicidad y la flexibilidad de los sistemas distribuidos. Según este principio, la inteligencia —la lógica— debe residir en los propios servicios (endpoints), no en los componentes de infraestructura que se usan para la integración (pipes). Los pipes —la infraestructura de mensajería y los canales de comunicación— solo deben encargarse de transportar datos entre servicios de forma confiable. El objetivo es reducir las dependencias entre servicios, lo que facilita el escalado, la depuración y un desarrollo más ágil, y evita los cuellos de botella y la complejidad típicos del middleware sofisticado.

Con esto en mente, llegó el momento de hablar de las otras opciones de mensajería disponibles en AWS.

Servicios alternativos de entrega de mensajes

Como mencioné en la introducción, hay muchas otras soluciones administradas por AWS relacionadas con la mensajería. Aquí quiero abordar brevemente otras opciones y por qué considero que la solución descrita arriba encaja mejor en el 80% de los casos.

EventBridge

La primera "S" de SNS y SQS significa "simple", y no está ahí por casualidad. SNS y SQS son servicios simples. EventBridge es mucho más flexible en cuanto a filtrado y reglas de enrutamiento de mensajes. En mi opinión, se acerca más al concepto de un bus de mensajes empresarial de la época de SOA. En lugar de dumb pipes, obtienes un punto central para recibir y enrutar eventos entre todos los componentes del sistema, e incluso entre varios sistemas. EventBridge, por supuesto, tiene sus casos de uso, por ejemplo, cuando necesitas integrarte con sistemas de terceros.

Kinesis y MSK (Managed Kafka)

Tanto Kinesis como MSK son servicios para trabajar con datos en streaming. Se podría decir que los datos en streaming son un subconjunto de la arquitectura orientada a eventos. Ambos implican trabajar con mensajes que se publican y consumen de forma asíncrona. Sin embargo, el patrón de uso es distinto: mientras que la EDA tradicional se centra en eventos o mensajes individuales, trabajar con datos en streaming implica procesar flujos continuos de eventos relacionados, que las soluciones tradicionales de bus de mensajes no manejan con tanta eficiencia. De ahí que existan herramientas como Kinesis y MSK. Si no necesitas procesar flujos continuos de mensajes, herramientas más simples como SNS y SQS te darán un sistema más directo.

Amazon MQ

Amazon MQ es un servicio administrado de broker de mensajes para protocolos como ActiveMQ y RabbitMQ. Resulta especialmente útil para migrar sistemas legacy a la nube o para sistemas que tienen que ejecutarse sin cambios en varios entornos cloud. Si bien Amazon MQ ofrece un broker de mensajes con todas las funciones y soporte para patrones avanzados, conlleva una carga operativa y una complejidad adicionales frente a la simplicidad de SNS y SQS.

Posts de la serie

  1. Arquitectura orientada a eventos en AWS, Parte I: lo básico (post actual)
  2. Arquitectura orientada a eventos en AWS, Parte II: lo básico avanzado
  3. Arquitectura orientada a eventos en AWS, Parte III: lo básico difícil

Publicado originalmente en https://vladikk.com .

En este post se abordó cómo implementar una arquitectura orientada a eventos (EDA) en AWS usando SNS y SQS para publicar y consumir eventos. Viste cómo SNS y SQS, en conjunto, conforman una solución simple y económica, con límites de propiedad claros, que aporta flexibilidad y tolerancia a fallos.