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

9.3 KiB
Raw Blame History

title localeTitle
Async messaging with RabbitMQ and Tortoise Асинхронные сообщения с помощью RabbitMQ и Tortoise

RabbitMQ - это самые простые и эффективные платформы для брокерских сообщений, использующие сегодня протокол AMQ. Использование его в архитектуре микросервиса приводит к увеличению производительности, а также к надежности. В этом руководстве мы рассмотрим основы использования RabbitMQ с Node.js.

теория

На самом базовом уровне вы идеально должны иметь две разные службы, взаимодействующие друг с другом через Rabbit - издателя и подписчика . Издатель обычно передает сообщения Кролику, и абонент слушает эти сообщения и выполняет код на основе этих сообщений. Обратите внимание, что они могут быть одновременно одновременно - служба может публиковать сообщения в Rabbit и потреблять сообщения одновременно, что позволяет создавать действительно мощные системы.

Теперь издатель обычно публикует сообщения с ключом маршрутизации к тому, что называется обменом . Потребитель слушает очередь на том же обмене, привязанный к ключу маршрутизации. В архитектурном плане ваша платформа будет использовать один обмен кролика, а разные виды заданий / сервисов будут иметь свои собственные ключи и очереди маршрутизации, чтобы pub-sub работал эффективно. Сообщения могут быть строками; они также могут быть родными объектами - клиентские библиотеки AMQP делают тяжелый подъем конвертируемых объектов с одного языка на другой. И да, это означает, что услуги могут быть написаны на разных языках, если они способны понимать AMQP.

Начиная

Мы собираемся подготовить очень простой пример, когда скрипт издателя публикует сообщение для Rabbit, содержащее URL-адрес, а потребительский скрипт прослушивает Rabbit, выдает опубликованный URL-адрес, вызывает его и отображает результаты. Вы можете найти готовый образец на Github .

Сначала давайте инициализируем проект npm:

$ npm init

Вы всегда можете просто нажать Enter полностью и использовать параметры по умолчанию - или вы можете их заполнить. Теперь давайте установим нужные нам пакеты. Мы будем использовать Tortoise , чтобы взаимодействовать с RabbitMQ. Мы также будем использовать node-cron , чтобы запланировать фактическую публикацию сообщений.

$ npm install --save tortoise node-cron

Теперь ваш package.json должен выглядеть так:

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

Теперь мы все настроены. Давайте сначала создадим издателя.

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

После импорта tortoise и node-cron мы пошли вперед и инициализировали соединение с RabbitMQ. Затем, давайте напишем быструю и грязную функцию, которая публикует сообщение для Rabbit:

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

Это достаточно просто. Мы определили словарь, содержащий URL-адрес для API RandomUser.me , который затем публикуется на random-user-exchange на RabbitMQ с помощью random-user-key маршрутизации с random-user-key доступом . Как упоминалось ранее, ключ маршрутизации определяет, кто получает сообщение. Теперь давайте напишем правило планирования, чтобы опубликовать это сообщение каждые 60 секунд.

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

И наш издатель готов! Но действительно бесполезно, если потребитель не потребляет эти сообщения! Но сначала нам нужна библиотека, которая может вызывать URL-адрес в этих сообщениях. Лично я использую superagent : npm install --save superagent .

Теперь, в consumer.js :

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

Далее, давайте напишем функцию async, которая вызывает URL-адрес и отображает результат:

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

Время написания кода для фактического потребления сообщений:

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

Здесь мы сказали tortoise прослушивать random-user-queue , которая привязана к random-user-key при random-user-exchange . После получения сообщения полезная нагрузка извлекается из msg и передается вместе с функцией getURL , которая, в свою очередь, возвращает Promise с требуемым ответом JSON от API RandomUser.

Вывод

Простота, связанная с использованием RabbitMQ для обмена сообщениями, не имеет себе равных, и очень легко придумать действительно сложные микросервисные шаблоны с несколькими строками кода. Лучшая часть заключается в том, что логика обмена сообщениями на самом деле не меняется на разных языках - Crystal или Go или Python или Ruby работают с Rabbit почти так же - это означает, что вы можете иметь услуги, написанные на разных языках, все общающиеся друг с другом без усилий , позволяя вам использовать лучший язык для работы.