Я пытаюсь найти практический / рекомендуемый способ извлечения сервисов, разделяя их на их собственные экземпляры, следуя стилю микросервисов. По этому поводу на лендинге перьев есть интересное высказывание:
Сервис-ориентированность: Feathers. Предоставляет вам структуру для создания сервис-ориентированных приложений с первого дня. Когда вам в конечном итоге потребуется разделить приложение на микросервисы, это будет простой переход, и ваши приложения можно безболезненно масштабировать.
Но я все еще не мог найти информацию о том, как справиться с этим вариантом использования в перьях.
С практической точки зрения, я изначально сосредотачиваюсь на двух основных темах:
Заранее спасибо!
Вы правы, документации пока не так много, и мы недавно создали https://github.com/feathersjs/feathers/issues/157, чтобы отслеживать это. Вот некоторые из моих мыслей по двум упомянутым вами темам:
Предположим, у нас изначально есть сервер с двумя сервисами, может что-то вроде
app.use('/users', memory())
.use('/todos', memory());
Сервис пользователей получает больше трафика, чем может обработать один сервер, поэтому мы хотим переместить его в другую систему, создав для него другое приложение:
// server1
app.use('/users', memory());
// server2
app.use('/todos', memory());
Чтобы служба /todos
теперь могла взаимодействовать с удаленной службой, мы можем использовать Feathers в качестве клиента для подключения к ней (веб-узлы быстрые и двунаправленные, так почему бы не использовать их для связи между серверами?):
// server2
const client = require('feathers/client')
const socketClient = require('feathers-socketio/client');
const io = require('socket.io-client');
const socket = io('http://other-server.com');
const otherApp = client().configure(socketClient(socket));
app.use('/todos', memory())
.use('/users', otherApp.service('users'));
Это в основном прозрачно передает пользовательскую службу удаленной службе через соединение через веб-сокет. Все, что использует исходную конечную точку /users
, ничего менять не должно.
Что касается аутентификации, есть много разных вариантов. В приведенном выше сценарии самым простым способом было бы для server1
просто внести в белый список IP-адреса других серверов, поскольку server2
по-прежнему является единственной точкой связи для клиентов. В конечном итоге server2
может просто стать шлюзом, который обрабатывает аутентификацию пользователя, а затем просто передает служебные вызовы другим серверам (которым не нужно беспокоиться об аутентификации, кроме проверки исходного IP-адреса).
Спасибо за ответ! Планируете ли вы освещать эту тему в официальных документах (возможно, в подразделе Руководств)? Сообщите мне, могу ли я внести свой вклад в этом отношении.
Определенно. И нам определенно нужна помощь. Может быть, давайте сначала соберем то, что мы хотели бы видеть в руководстве, а затем сделаем несколько демонстрационных приложений?
💯 @daffl - это
@daffl Подход, о котором вы упомянули, с использованием пера-клиента в серверной микросервисе, позволяет двунаправленную связь посредством потоковой передачи данных, поскольку используется socket.io. У Feathers уже есть семантика / API для этого сценария? Я думаю о ситуации, когда микросервис публикует событие для других заинтересованных микросервисов, а не для клиента браузера.
Да, но почему другие заинтересованные службы не могут также использовать веб-сокеты? Мы думаем о добавлении других поставщиков (например, для различных служб обмена сообщениями), но на данный момент веб-сокеты кажутся достаточно быстрыми, и нигде не написано, что их можно использовать только в браузере.
@daffl @ekryski по мере распространения приложений из перьев нам также необходимо будет решить такие проблемы, как хотя бы однократная доставка (acks), идемпотентность, транзакции, противодавление (очереди) и т. д., рассматривали ли вы что-то вроде "службы перьев" рабочий? ".. т.е. внешние процессы, которые потребляют события из постоянной очереди amqp (например, rabbitmq) или redis (с использованием, например, kue)?
@daffl Думаю, я плохо понял до вашего ответа. Пока заинтересованные службы используют веб-сокеты для подписки на службу производителя, используя API регулярных событий для публикации новых событий производителя, этого достаточно, чтобы реализовать это в перьях, верно?
Я согласен с @justingreenberg , еще одна проблема, которую необходимо решить, - это повторное воспроизведение запросов, когда ответственные микросервисы отключаются (сбой, обновления и т. Д.). Технически это тоже можно было бы решить с помощью очередей сообщений.
Есть ли в этом прогресс? Мне бы очень хотелось увидеть некоторую документацию / рабочий пример. Особенно в отношении того, как обрабатывается аутентификация.
@imns, мы над этим работаем. Я начал работать над примером и разделением приложения, и мы поняли, что существуют некоторые ограничения в настройке аутентификации. Итак, в настоящее время мы проводим рефакторинг auth, чтобы лучше поддерживать это. Должно пройти около недели, чтобы он приземлился.
Ой, я мог бы использовать это так плохо прямо сейчас: D
Просто из любопытства вы переделываете auth для работы с несколькими интерфейсами? Я думаю, что сейчас многие более крупные приложения используют микросервисы на бэкэнде, но также ломают свои интерфейсные приложения.
Если у вас есть лишние деньги, я думаю, эту книгу можно было бы рекомендовать к прочтению: https://www.amazon.com/Building-Microservices-Sam-Newman/dp/1491950358/ref=sr_1_1 ? Ie = UTF8 & qid = 1469071253 & sr = 8-1 & ключевые слова = микросервисы
Ребят, есть обновления по этому поводу? Спасибо.
@juanpujol, самая свежая информация всегда будет в этом билете. Тем не менее, спасибо за проверку.
(здесь Маркфавзи)
Я не читал весь поток, но предполагаю, что мы сможем использовать базу данных для каждой службы (в архитектуре Micreoservices такое разделение имеет решающее значение для поддержания абстракции. В противном случае, если все службы используют одну и ту же базу данных, что мешает людям от определения отношений между моделями сервисов (нарушение абстракции микросервисов) вместо создания сервисов с использованием единого API сервиса?
На самом деле ничто не мешает этому, я бы сказал, что вы не должны этого делать. Это действительно будет проблемой, только если вы определите свои модели и отношения на уровне ORM. Я не думаю, что установление отношений на уровне обслуживания путем обращения к другим службам нарушает абстракцию микросервисов.
Да именно то, что я имел в виду. Я склонен думать, что разделение служб, где каждая служба имеет свою собственную базу данных, является верным способом принудительной компоновки через интерфейс службы, а не на уровне ORM.
Но Feathers является более общим, чем фреймворк микросервисов, так что здесь все хорошо. Спасибо, Дэвид! Чем больше я вникаю в это, тем лучше и лучше выглядит! Отличная работа со всех сторон!
Просто подумал, что упомяну об этом здесь, так как это решает некоторые проблемы, возникающие при использовании Feathers в среде микросервисов. Это только первая реализация, но если у вас есть что добавить, не стесняйтесь здесь https://github.com/zapur1/feathers-rabbitmq/issues/1
@ zapur1 выглядит многообещающе ... Я опубликовал комментарий, чтобы начать обсуждение
Вы также можете использовать https://github.com/feathersjs/feathers-sync с rabbitMQ, Redis или MongoDB в качестве брокеров сообщений между службами, чтобы синхронизировать их все.
@ekryski feathers-sync
решает немного другую проблему: что, если вы хотите, чтобы событие было получено только один раз в области именованной службы (не службы Feathers, а службы стиля микросервисов)? Если у вас было несколько экземпляров одной службы, получающей события от одного приложения API, каждый из них получит событие, вероятно, дублирующее действия, предпринимаемые при получении этого события несколькими экземплярами одного и того же кода.
@ekryski Я только что снова взглянул на репо, и zapur1 / перья-rabbitmq решает именно ту проблему, которую вы упомянули в «Предостережениях».
если я подключаю службу 1 к службе 2 с помощью socketClient, поэтому, если моя служба 2 имеет несколько экземпляров, как я могу реализовать баланс нагрузки :(
Если я создам отдельное серверное приложение, которое подключается через socketClient, каков наилучший способ аутентификации, чтобы любая из служб была доступна независимо от любых установленных ограничений.
Я добавляю свои 2 цента к этому с https://github.com/kalisio/feathers-distributed , он направлен на развертывание N приложений перьев, в которых разные службы взаимодействуют вместе, чтобы вы могли разрабатывать каждое из них независимо. Он отличается от https://github.com/feathersjs/feathers-sync, который, насколько я понимаю, направлен на развертывание N приложений с одинаковыми сервисами. Все это вызывает ряд вопросов, например:
@daffl в приведенном вами примере с участием сервера 1 и сервера 2, как бы вы /users
на сервере 2? Если бы у нас была эта служба, определенная на сервере 2, мы могли бы использовать перехватчики в конкретном файле перехватов службы, но, поскольку мы делаем app.use('/users', otherApp.service('users'));
, как бы мы могли убедиться, что вызовы этой службы с сервера 2 будут выполняться только если пользователь аутентифицировался первым?
РЕДАКТИРОВАТЬ:
Nvm, я думаю, у меня есть идея: мы могли бы сделать что-то вроде const usersService = app.service('users')
а затем usersService.hooks(hooks)
где у хуков есть хуки авторизации, необходимые для защиты конечной точки, правильно?
Я написал больше о том, как можно выполнить распределенную аутентификацию, в https://stackoverflow.com/questions/41076627/evaluating-featherjs-authentication-needs/41095638#41095638 :
Существует несколько способов разделения услуг, каждый из которых имеет свои преимущества и недостатки. Для Feathers важно то, что сеансов нет, есть только веб-токены JSON. JWT не имеют состояния и могут быть прочитаны любым сервером, который использует один и тот же секрет, поэтому нет необходимости в центральном хранилище сеансов. Я могу придумать два основных варианта:
Самый полезный комментарий
Вы правы, документации пока не так много, и мы недавно создали https://github.com/feathersjs/feathers/issues/157, чтобы отслеживать это. Вот некоторые из моих мыслей по двум упомянутым вами темам:
Предположим, у нас изначально есть сервер с двумя сервисами, может что-то вроде
Сервис пользователей получает больше трафика, чем может обработать один сервер, поэтому мы хотим переместить его в другую систему, создав для него другое приложение:
Чтобы служба
/todos
теперь могла взаимодействовать с удаленной службой, мы можем использовать Feathers в качестве клиента для подключения к ней (веб-узлы быстрые и двунаправленные, так почему бы не использовать их для связи между серверами?):Это в основном прозрачно передает пользовательскую службу удаленной службе через соединение через веб-сокет. Все, что использует исходную конечную точку
/users
, ничего менять не должно.Что касается аутентификации, есть много разных вариантов. В приведенном выше сценарии самым простым способом было бы для
server1
просто внести в белый список IP-адреса других серверов, посколькуserver2
по-прежнему является единственной точкой связи для клиентов. В конечном итогеserver2
может просто стать шлюзом, который обрабатывает аутентификацию пользователя, а затем просто передает служебные вызовы другим серверам (которым не нужно беспокоиться об аутентификации, кроме проверки исходного IP-адреса).