Я пишу некоторые микросервисы, используя Перья.Довольно плохо знаком с Feathers (и Node в целом) и столкнулся с проблемой.
Для связи между микросервисами (т. Е. Набором независимых приложений Feathers) я собираюсь использовать RabbitMQ (брокер сообщений AMQP).).После вызова определенных методов обслуживания я хотел бы опубликовать сообщение через AMQP.Точно так же я хотел бы, чтобы приложение подписывалось на обмен в брокере и вызывало метод обслуживания при получении определенного сообщения.
Поскольку у меня есть около десятка микросервисов, я решил написать библиотеку, которая обрабатываеттакие вещи, как усиление структуры темы и повторное подключение и т. д. Библиотека - это всего лишь оболочка для amqplib.Я знаю, что несколько плавающих модулей с открытым исходным кодом amqp плавают вокруг, но ни один из них не делает именно то, что я хочу.
В библиотеке есть метод connect (), метод publish () и подписка () метод.Метод connect () принимает URL-адрес, подключается к брокеру и сохраняет объект подключения в переменной модуля.
Планируется зарегистрировать метод publish () в качестве ловушки в каждой из соответствующих служб.Например, если бы у меня был сервис под названием foo, он мог бы иметь foo.hooks.js:
module.exports = {
before: {
all: [],
find: [],
get: [],
create: [amqpWrapper.publish()],
update: [amqpWrapper.publish()],
patch: [amqpWrapper.publish()],
remove: [amqpWrapper.publish()]
}
//etc
};
, где метод publish () захватывает объект контекста, извлекает необходимую ему информацию и вытаскивает ее через amqp.
И foo.service.js:
// Initializes the `crunch` service on path `/foo`
const createService = require('feathers-nedb');
const createModel = require('../../models/crunch.model');
const hooks = require('./crunch.hooks');
module.exports = function (app) {
const Model = createModel(app);
const paginate = app.get('paginate');
const options = {
Model,
paginate
};
// Initialize our service with any options it requires
app.use('/foo', createService(options));
// Get our initialized service so that we can register hooks
const service = app.service('foo');
service.hooks(hooks);
};
У меня может быть очень похожая служба, называемая bar, которая также публикует в своих хуках.
Проблема заключается в том, что вы должны поддерживать толькоодно соединение на один процесс с rabbitmq.Открытие и закрытие соединения происходит медленно, поэтому в идеале я просто хочу вызвать метод connect () один раз при запуске приложения, чтобы он сохранялся и был глобально доступен из всех моих различных служб.
Конечно, я мог быпросто сделай
const amqpWrapper = require('amqpWrapper')
Во всех файлах [service] .hooks.js, а также в index.js верхнего уровня, где я бы также вызвал connectMethod (), ноэто не кажется мне правильным.В Javascript на самом деле нет синглетов, и хотя он использует кеширование для require (), он не гарантирован.
Итак, каков правильный способ импорта модуля с постоянным соединением, который доступен везде вПерья?Могу ли я как-то сохранить его в объекте 'app'?
Редактировать
Следовал предложению Даффа, и это работает, но просто хотел расширить полное решение:
Так как мой amqpWrapper () возвращает модуль библиотеки module.exports, я сохраняю соединение в /src/app.js, используя app.set('amqp', amqpWrapper.connect())
, а затем в моем foo.hooks.js, я просто делаю:
module.exports = {
after: {
all: [],
find: [],
get: [],
create: [context => {context.app.get('amqp').publish();}],
update: [],
patch: [],
remove: []
},
//etc
};