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

125 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
title: Async messaging with RabbitMQ and Tortoise
localeTitle: Асинхронные сообщения с помощью RabbitMQ и Tortoise
---
RabbitMQ - это самые простые и эффективные платформы для брокерских сообщений, использующие сегодня протокол AMQ. Использование его в архитектуре микросервиса приводит к увеличению производительности, а также к надежности. В этом руководстве мы рассмотрим основы использования RabbitMQ с Node.js.
## теория
На самом базовом уровне вы идеально должны иметь две разные службы, взаимодействующие друг с другом через Rabbit - _издателя_ и _подписчика_ . Издатель обычно передает сообщения Кролику, и абонент слушает эти сообщения и выполняет код на основе этих сообщений. Обратите внимание, что они могут быть одновременно одновременно - служба может публиковать сообщения в Rabbit и потреблять сообщения одновременно, что позволяет создавать действительно мощные системы.
Теперь издатель обычно публикует сообщения с _ключом маршрутизации_ к тому, что называется _обменом_ . Потребитель слушает _очередь_ на том же обмене, привязанный к ключу маршрутизации. В архитектурном плане ваша платформа будет использовать один обмен кролика, а разные виды заданий / сервисов будут иметь свои собственные ключи и очереди маршрутизации, чтобы pub-sub работал эффективно. Сообщения могут быть строками; они также могут быть родными объектами - клиентские библиотеки AMQP делают тяжелый подъем конвертируемых объектов с одного языка на другой. И да, это означает, что услуги могут быть написаны на разных языках, если они способны понимать AMQP.
## Начиная
Мы собираемся подготовить очень простой пример, когда скрипт издателя публикует сообщение для Rabbit, содержащее URL-адрес, а потребительский скрипт прослушивает Rabbit, выдает опубликованный URL-адрес, вызывает его и отображает результаты. Вы можете найти готовый образец на [Github](https://github.com/rudimk/freecodecamp-guides-rabbitmq-tortoise) .
Сначала давайте инициализируем проект npm:
`$ npm init`
Вы всегда можете просто нажать `Enter` полностью и использовать параметры по умолчанию - или вы можете их заполнить. Теперь давайте установим нужные нам пакеты. Мы будем использовать [Tortoise](https://www.npmjs.com/package/tortoise) , чтобы взаимодействовать с RabbitMQ. Мы также будем использовать [node-cron](https://www.npmjs.com/package/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"
}
}
```
Теперь мы все настроены. Давайте сначала создадим издателя.
```javascript
const Tortoise = require('tortoise')
const cron = require('node-cron')
const tortoise = new Tortoise(`amqp://rudimk:YouKnowWhat@$localhost:5672`)
```
После импорта `tortoise` и `node-cron` мы пошли вперед и инициализировали соединение с RabbitMQ. Затем, давайте напишем быструю и грязную функцию, которая публикует сообщение для Rabbit:
```javascript
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](https://randomuser.me/) , который затем публикуется на `random-user-exchange` на RabbitMQ с помощью `random-user-key` маршрутизации с `random-user-key` [доступом](https://randomuser.me/) . Как упоминалось ранее, ключ маршрутизации определяет, кто получает сообщение. Теперь давайте напишем правило планирования, чтобы опубликовать это сообщение каждые 60 секунд.
```javascript
cron.schedule('60 * * * * *', scheduleMessage)
```
И наш издатель готов! Но действительно бесполезно, если потребитель не потребляет эти сообщения! Но сначала нам нужна библиотека, которая может вызывать URL-адрес в этих сообщениях. Лично я использую `superagent` : `npm install --save superagent` .
Теперь, в `consumer.js` :
```javascript
const Tortoise = require('tortoise')
const superagent = require('superagent')
const tortoise = new Tortoise(`amqp://rudimk:YouKnowWhat@$localhost:5672`)
```
Далее, давайте напишем функцию async, которая вызывает URL-адрес и отображает результат:
```javascript
async function getURL(url){
let response = await superagent.get(url)
return response.body
}
```
Время написания кода для фактического потребления сообщений:
```javascript
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 почти так же - это означает, что вы можете иметь услуги, написанные на разных языках, все общающиеся друг с другом без усилий , позволяя вам использовать лучший язык для работы.