freeCodeCamp/guide/spanish/javascript/async-messaging-with-rabbit.../index.md

6.6 KiB

title localeTitle
Async messaging with RabbitMQ and Tortoise Mensajes asíncronos con RabbitMQ y Tortoise

Resulta que RabbitMQ es la plataforma de intermediarios de mensajes más fácil y con más rendimiento que utiliza el protocolo AMQ que existe hoy en día. Su uso en una arquitectura de microservicio se traduce en ganancias de rendimiento masivas, así como en la promesa de confiabilidad. En esta guía, vamos a explorar los conceptos básicos del uso de RabbitMQ con Node.js.

Teoría

En su nivel más básico, lo ideal sería tener dos servicios diferentes que interactúen entre sí a través de Rabbit: un editor y un suscriptor . Un editor normalmente envía mensajes a Rabbit, y un suscriptor escucha estos mensajes y ejecuta el código basándose en esos mensajes. Tenga en cuenta que pueden ser ambos al mismo tiempo; un servicio puede publicar mensajes en Rabbit y consumir mensajes al mismo tiempo, lo que hace que se diseñen sistemas realmente potentes.

Ahora, un editor generalmente publica mensajes con una clave de enrutamiento a algo que se llama intercambio . Un consumidor escucha una cola en el mismo intercambio, vinculado a la clave de enrutamiento. En términos arquitectónicos, su plataforma usaría un intercambio de Rabbit, y diferentes tipos de trabajos / servicios tendrían sus propias claves de enrutamiento y colas, para que pub-sub funcione de manera efectiva. Los mensajes pueden ser cadenas; también pueden ser objetos nativos: las bibliotecas cliente de AMQP hacen el trabajo pesado de convertir objetos de un idioma a otro. Y sí, eso significa que los servicios se pueden escribir en diferentes idiomas, siempre que puedan entender el AMQP.

Empezando

Vamos a preparar un ejemplo muy simple en el que un script de editor publica un mensaje para Rabbit, que contiene una URL, y un script de consumidor escucha a Rabbit, toma la URL publicada, la llama y muestra los resultados. Puedes encontrar la muestra terminada en Github .

Primero, inicialicemos un proyecto npm:

$ npm init

Siempre puede simplemente presionar Enter todo el camino y usar las opciones predeterminadas, o puede completarlas. Ahora, instalemos los paquetes que necesitamos. Vamos a utilizar Tortoise , para interactuar con RabbitMQ. También vamos a utilizar node-cron , para programar la publicación del mensaje real.

$ npm install --save tortoise node-cron

Ahora su package.json debería parecerse mucho a esto:

{ 
  "name": "freecodecamp-guides-rabbitmq-tortoise", 
  "version": "1.0.0", 
  "description": "Sample code to accompany the FreeCodeCamp guide on async messaging with RabbitMQ and Tortoise.", 
  "main": "index.js", 
  "scripts": { 
    "test": "echo \"Error: no test specified\" && exit 1" 
  }, 
  "repository": { 
    "type": "git", 
    "url": "git+https://github.com/rudimk/freecodecamp-guides-rabbitmq-tortoise.git" 
  }, 
  "keywords": [ 
    "rabbitmq", 
    "tortoise", 
    "amqp" 
  ], 
  "author": "Rudraksh MK", 
  "license": "MIT", 
  "bugs": { 
    "url": "https://github.com/rudimk/freecodecamp-guides-rabbitmq-tortoise/issues" 
  }, 
  "homepage": "https://github.com/rudimk/freecodecamp-guides-rabbitmq-tortoise#readme", 
  "dependencies": { 
    "node-cron": "^1.2.1", 
    "tortoise": "^1.0.1" 
  } 
 } 

Ahora estamos listos. Vamos a crear un editor primero.

const Tortoise = require('tortoise') 
 const cron = require('node-cron') 
 
 const tortoise = new Tortoise(`amqp://rudimk:YouKnowWhat@$localhost:5672`) 

Después de importar tortoise y node-cron , hemos avanzado e inicializado una conexión a RabbitMQ. A continuación, escribamos una función rápida y sucia que publica un mensaje para Rabbit:

function scheduleMessage(){ 
    let payload = {url: 'https://randomuser.me/api'} 
    tortoise 
    .exchange('random-user-exchange', 'direct', { durable:false }) 
    .publish('random-user-key', payload) 
 } 

Eso es bastante simple. Hemos definido un diccionario que contiene una URL para la API RandomUser.me , que luego se publica en el random-user-exchange intercambio de random-user-exchange en RabbitMQ, con la random-user-key enrutamiento de claves de random-user-key . Como se mencionó anteriormente, la clave de enrutamiento es lo que determina quién puede consumir un mensaje. Ahora, escribamos una regla de programación, para publicar este mensaje cada 60 segundos.

cron.schedule('60 * * * * *', scheduleMessage) 

¡Y nuestro editor está listo! ¡Pero realmente no es bueno que un consumidor consuma estos mensajes! Pero primero, necesitamos una biblioteca que pueda llamar a la URL en estos mensajes. Personalmente, uso superagent : npm install --save superagent .

Ahora, en consumer.js :

const Tortoise = require('tortoise') 
 const superagent = require('superagent') 
 
 const tortoise = new Tortoise(`amqp://rudimk:YouKnowWhat@$localhost:5672`) 

A continuación, escribamos una función asíncrona que llame a una URL y muestre el resultado:

async function getURL(url){ 
    let response = await superagent.get(url) 
    return response.body 
 } 

Es hora de escribir código para realmente consumir mensajes:

tortoise 
 .queue('random-user-queue', { durable: false }) 
 // Add as many bindings as needed 
 .exchange('random-user-exchange', 'direct', 'random-user-key', { durable: false }) 
 .prefetch(1) 
 .subscribe(function(msg, ack, nack) { 
  // Handle 
  let payload = JSON.parse(msg) 
  getURL(payload['url']).then((response) => { 
    console.log('Job result: ', response) 
  }) 
  ack() // or nack() 
 }) 

Aquí, le hemos dicho a tortoise que escuche la random-user-queue , que está vinculada a la random-user-key random-user-exchange . Una vez que se recibe un mensaje, la carga útil se recupera de msg y se pasa a la función getURL , que a su vez devuelve una Promesa con la respuesta JSON deseada de la API de RandomUser.

Conclusión

La simplicidad asociada con el uso de RabbitMQ para la mensajería no tiene paralelo, y es muy fácil crear patrones de microservicio realmente complejos, con solo unas pocas líneas de código. La mejor parte es que la lógica detrás de la mensajería no cambia realmente a través de los idiomas: Crystal o Go o Python o Ruby funcionan de la misma manera con Rabbit; esto significa que puede tener servicios escritos en diferentes idiomas, todos los cuales se comunican entre sí sin esfuerzo. , permitiéndole utilizar el mejor lenguaje para el trabajo.