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

6.5 KiB

title localeTitle
Async messaging with RabbitMQ and Tortoise Mensagens assíncronas com RabbitMQ e Tortoise

O RabbitMQ é, por acaso, a plataforma de mensagens mais fácil e eficiente com o protocolo AMQ existente hoje. Usá-lo em uma arquitetura de microsserviço se traduz em enormes ganhos de desempenho, bem como a promessa de confiabilidade. Neste guia, vamos explorar os fundamentos do uso do RabbitMQ com o Node.js.

Teoria

Em seu nível mais básico, você idealmente teria dois serviços diferentes interagindo uns com os outros através do Rabbit - um editor e um assinante . Um editor normalmente envia mensagens para o Rabbit e um assinante escuta essas mensagens e executa o código com base nessas mensagens. Note que eles podem ser ambos ao mesmo tempo - um serviço pode publicar mensagens para o Rabbit e consumir mensagens ao mesmo tempo, o que faz com que sistemas realmente poderosos sejam projetados.

Agora, um editor normalmente publica mensagens com uma chave de roteamento para algo chamado troca . Um consumidor escuta uma fila na mesma troca, vinculada à chave de roteamento. Em termos de arquitetura, sua plataforma usaria uma troca de coelho, e diferentes tipos de trabalhos / serviços teriam suas próprias chaves de roteamento e filas, para que o pub-sub funcionasse de forma eficaz. Mensagens podem ser seqüências de caracteres; eles também podem ser objetos nativos - as bibliotecas cliente AMQP fazem o trabalho pesado de converter objetos de um idioma para outro. E sim, isso significa que os serviços podem ser escritos em diferentes idiomas, desde que sejam capazes de entender o AMQP.

Começando

Vamos elaborar um exemplo muito simples em que um script do editor publica uma mensagem para o Rabbit, contendo um URL, e um script do consumidor escuta o Rabbit, pega o URL publicado, chama e exibe os resultados. Você pode encontrar a amostra finalizada no Github .

Primeiro, vamos inicializar um projeto npm:

$ npm init

Você sempre pode simplesmente pressionar Enter até o fim e usar as opções padrão - ou você pode preenchê-las. Agora, vamos instalar os pacotes que precisamos. Nós vamos usar o Tortoise , para interagir com o RabbitMQ. Também vamos usar o node-cron para agendar a publicação de mensagens real.

$ npm install --save tortoise node-cron

Agora o seu package.json deve ficar muito parecido com isto:

{ 
  "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" 
  } 
 } 

Agora estamos todos prontos. Vamos criar um editor primeiro.

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

Depois de importar tortoise e node-cron , fomos em frente e inicializamos uma conexão com o RabbitMQ. Em seguida, vamos escrever uma função rápida e suja que publique uma mensagem para o Rabbit:

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

Isso é bem simples. Definimos um dicionário que contém um URL para a API RandomUser.me , que é então publicado na random-user-exchange troca de random-user-exchange no RabbitMQ, com a random-user-key roteamento de chave de random-user-key . Como mencionado anteriormente, a chave de roteamento é o que determina quem consegue consumir uma mensagem. Agora, vamos escrever uma regra de agendamento para publicar essa mensagem a cada 60 segundos.

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

E nossa editora está pronta! Mas não é nada bom sem um consumidor consumir essas mensagens! Mas primeiro, precisamos de uma biblioteca que possa chamar o URL nessas mensagens. Pessoalmente, eu uso superagent : npm install --save superagent .

Agora, em consumer.js :

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

Em seguida, vamos escrever uma função assíncrona que chama um URL e exibe o resultado:

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

Hora de escrever código para consumir mensagens:

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() 
 }) 

Aqui, nós dissemos a tortoise para ouvir a random-user-queue , que está ligada à random-user-key random-user-exchange . Quando uma mensagem é recebida, a carga é recuperada da msg e é passada para a função getURL , que por sua vez retorna um Promise com a resposta JSON desejada da API RandomUser.

Conclusão

A simplicidade associada ao uso do RabbitMQ para mensagens é incomparável, e é muito fácil criar padrões de microsserviço realmente complexos, com apenas algumas linhas de código. A melhor parte é que a lógica por trás das mensagens realmente não muda entre as linguagens - Crystal ou Go ou Python ou Ruby trabalham com Rabbit da mesma maneira - isso significa que você pode ter serviços escritos em diferentes idiomas, comunicando-se sem esforço. , permitindo que você use a melhor linguagem para o trabalho.