Hoy en día es muy común que los equipos de desarrollo de software decidan utilizar microservicios como patrón de diseño antes que decantarse por un diseño monolítico. Esto se debe principalmente a que en las arquitecturas monolíticas todos los procesos están relacionados y se ejecutan como parte de un solo servicio y esto conlleva una serie de problemas entre los que podemos destacar los siguientes:
En las arquitecturas de microservicios, en cambio, cada microservicio es un sistema independiente, destinado a realizar una función específica dentro de la totalidad del sistema, y las comunicaciones entre los diferentes microservicios se realizan a través de una interfaz definida mediante API. Todo esto nos permite actualizar y escalar cada microservicio de forma independiente, es decir, sin verse afectados el resto de microservicios.
Pero no todo son ventajas, la arquitectura de microservicios también presenta una serie de inconvenientes que surgen de su naturaleza. Un microservicio al ser un sistema independiente es muy probable que tenga su propia base de datos y hay operaciones que pueden necesitar el uso de más de un microservicio por lo que requerimos de algún mecanismo para asegurar que existe consistencia de datos entre los diferentes microservicios. Si bien es cierto que mediante las interfaces API definidas podemos establecer comunicación entre los microservicios, esta no es la mejor opción, dado que a medida que escala la base del código estas relaciones pueden llegar a ser algo complejas. Para solventar este inconveniente existe la llamada Event-Driven Architecture(EDA).
Este patrón de diseño establece que cada vez que la base de datos de un microservicio se ve actualizada, este lanza un evento y el resto de microservicios que necesiten actualizar sus datos o realizar alguna operación se suscriben a dicho evento. Como se puede apreciar, la principal ventaja de este patrón es que nos aseguramos que existe consistencia de datos entre los microservicios de nuestra aplicación sin tener que usar transacciones distribuidas.
Veamos un ejemplo, supongamos que tenemos una aplicación en la que se venden productos y cada usuario tiene un cesto de la compra para ir añadiendo todos los productos que quiere comprar. Una forma de organizar todas las funcionalidades que requiere la aplicación descrita podría ser la siguiente:
Los usuarios pueden añadir ‘n’ productos en el cesto y, cuando lo consideren oportuno, pueden realizar el checkout de todo su cesto, pagar y los productos serán suyos. En el momento en el que queremos realizar dicho checkout tienen que sucederse varias operaciones en los diferentes microservicios. Por un lado, en el product service tenemos que restar disponibilidad a los productos seleccionados, por otro lado, tenemos que vaciar la cesta en el basket service y por último tenemos que confirmar el pago y crear el pedido en el ordering service. Si no tuviéramos implementado el EDA deberíamos de realizar todos los pasos mencionados al confirmar el checkout. Pero al tener EDA implementado usando EventBridge de AWS(que veremos más adelante) es tan sencillo como lanzar un evento por un bus específico al realizar el checkout. Entonces, desde los servicios que se vean afectados por esta operación deberán añadir una funcionalidad para escuchar dicho evento y realizar las acciones pertinentes.
AWS nos brinda un servicio llamado EventBridge que, citando la documentación oficial, consiste en un bus de eventos que facilita la creación de aplicaciones basadas en eventos a escala mediante eventos generados por sus aplicaciones. Tal y como se nos explica en AWS, EventBridge tiene las siguientes ventajas:
Aquí podemos observar que es EventBridge a nivel estructural en AWS:
Los eventos no son más que objetos JSON que contienen información relacionada con cambios que se han producido en otros servicios. Aquí podemos ver como ejemplo un evento de AWS cuando se termina una instancia EC2.
{
"version": "0",
"id": "6a7e8feb-b491-4cf7-a9f1-bf3703467718",
"detail-type": "EC2 Instance State-change Notification",
"source": "aws.ec2",
"account": "111122223333",
"time": "2017-12-22T18:43:48Z",
"region": "us-west-1",
"resources": [
"arn:aws:ec2:us-west-1:123456789012:instance/i-1234567890abcdef0"
],
"detail": {
"instance-id": " i-1234567890abcdef0",
"state": "terminated"
}
}
Pero no todos estos campos son requeridos a la hora de crear un evento en AWS, los únicos requeridos son:
En este blog hemos visto las principales diferencias entre un monolito y las arquitecturas de microservicios así como las mejoras que aporta la arquitectura EDA a estos. Por último, hemos visto qué servicios ofrece AWS para implementar EDA y la estructura básica de EventBridge.