Системные проблемы архитектуры микросервисов

#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. Рад это знать 🙂