#node.js #mongodb #rabbitmq #microservices
#node.js #mongodb #rabbitmq #микросервисы
Вопрос:
В данный момент я нахожусь в процессе написания своего нового приложения с архитектурой микросервисов. Небольшое краткое объяснение того, что будет делать мое приложение, заключается в следующем:
- Микросервис A очистит несколько страниц продуктов электронной коммерции и отправит все очищенные продукты 1 к 1 моему следующему микросервису, который с этого момента я буду называть B. Для каждого продукта, у которого нет задачи с
running: true
, он очищает продукт и создает новую задачу сrunning: true
. - Микросервис B будет обрабатывать каждый продукт (обновлять данные в моей базе данных), он получает и отправляет все измененные данные по сравнению с базой данных в мой следующий микросервис, который я теперь буду называть C .
- Микросервис C получает измененный продукт и отправляет сообщение на мой канал discord amp; slack. Когда это будет сделано, для текущей задачи для этого продукта будет установлено значение
running: false
В настоящее время я борюсь с тем, что я хочу, чтобы микросервис A снова начал очистку для продуктов, которые были обработаны микросервисом C. Для этого я подумал о какой-то системе задач, где с каждым очищаемым продуктом также связан идентификатор задачи. Единственная проблема, с которой я сталкиваюсь в настоящее время, заключается в том, что:
- Задача может зависнуть / завершиться сбоем или что-то еще. Чтобы попытаться решить эту проблему, у меня есть задачи, которые все еще выполняются (переменная в базе данных) и были запущены более 5 минут назад, автоматически остановлены. На мой взгляд, это не идеально, потому что это означает, что выполнение задачи может занять 5 минут.
- Поскольку каждому очищаемому продукту назначается 1 задача, мне пришлось бы быстро развернуть множество микросервисов B, чтобы правильно обрабатывать всю нагрузку.
Что я хотел бы спросить, так это, есть ли у кого-нибудь метод или совет о том, как улучшить / внедрить такую систему в моих микросервисах. Каждый продукт необходимо очищать сразу после завершения предыдущего. В настоящее время микросервис A просто проверяет, может ли он найти запущенную задачу для продукта с помощью setInterval.
Все это разработано в NodeJS, и вся информация сохраняется в базе данных MongoDB. Связь между микросервисами осуществляется через RabbitMQ.
Любая помощь очень ценится.
Комментарии:
1. Несколько запросов, 1. когда A простаивает, будет ли он снова обрабатывать задачу, выполняемую C, в основном со статусом в системе задач {выполняется: false, id: 123}, вы упомянули, что боретесь с этим правом и нуждаетесь в рекомендации / наилучших способах, касающихся только этого или в целом? 2. В последних нескольких строках вы упомянули, что m (A) проверяет
running : true
, чтобы найти данные продукта для утилизации. но зачем вам проверять запущенную задачу, если вы хотите обработать завершенную? пункты 1 и 2 кажутся мне парадоксом, не могли бы вы пояснить, пожалуйста?2. @bron10 Спасибо за ваш комментарий. Я отредактировал вопрос по этому поводу. В целом я хотел бы получить некоторые рекомендации / наилучшие способы по этому вопросу.
Ответ №1:
Я хотел бы добавить два момента к этой архитектуре. Кажется, что каждая микросервис изменяет состояние данных с течением времени, но источник данных тот же.
1. Почему бы не изменить статус данных в каждой микросервисе [состояние]?
На данный момент вы используете логическое значение для одного задания, которое вы начали running:true
. Мы можем изменить это на что-то вроде ['scrapping', 'compare', 'notify']
{
...
status : 'scrapping',
jobId : 23,
...
}
Теперь, когда данные, наконец, находятся в микросервисе C, он может опубликовать новое задание со статусом «уведомить» для потребителя
микросервис A, A может условно обработать этот сценарий и при необходимости повторно отобразить.
Другим преимуществом является то, что каждый микросервис может условно идентифицировать задание на основе статуса задания
также. Следовательно, в любых случаях сбоя или перезапуска каждый микросервис будет выполнять только определенную задачу
если это соответствует его критериям. Например, микросервис B не запустит задание, в котором нет
scrapping
как статус.
В принципе, подтвердите свою работу, только если она выполнена с помощью channel.ack(message)
.
2. Синхронизация данных
Я не буду рекомендовать создавать несколько микросервисов B в качестве потребителей, может возникнуть проблема с синхронизацией данных [в то время как несколько потребителей B работают на одной странице с разными продуктами] Либо вы можете измерить свой список продуктов на основе каждой страницы, соответствующим образом скорректировать конфигурацию очереди с помощью некоторого тестирования (но не слишком длинных очередей, поскольку это снизит скорость и повлияет на производительность), либо объединить их в одно задание и отправить его на обработку.
Узнайте больше о :
Комментарии:
1. Большое вам спасибо за информацию. Я только что закончил обновлять свой код с учетом вашего предложения, и на данный момент он работает безупречно!
2. Рад это знать 🙂