Одновременные потребители обеспечивают порядок
У меня есть очередь JMS, которая заполняется с очень высокой скоростью ( > 100000 в секунду).
Может случиться, что каждую секунду также может быть несколько сообщений, относящихся к одному и тому же объекту. (несколько обновлений сущности, каждое из которых представляет собой отдельное сообщение.)
С другой стороны, у меня есть один потребитель, который обрабатывает это сообщение и отправляет его другим приложениям.
Теперь все настройки замедляются, так как потребитель не может справиться со скоростью входящих сообщений.
Поскольку существует соглашение об уровне обслуживания, на котором потребитель обрабатывает сообщения, я думал о том, чтобы несколько потребителей действовали параллельно, чтобы ускорить процесс.
Итак, что я думаю сделать, это
- Несколько потребителей, действующих независимо от очереди.
- Каждый потребитель может получить любое сообщение.
- После получения сообщения убедитесь, что это последняя версия объекта. Для этого, часть, я могу проверить с приложением, которое обрабатывает эту сущность.
- если это не последняя версия, увеличьте версию и попробуйте снова.
Я до сих пор безуспешно искал шаблоны интеграции, документы JMS.
Я бы приветствовал идеи по более элегантному решению этой проблемы наряду с любыми известными API-интерфейсами и шаблонами в мире Java.
3 ответа
ActiveMQ решает эту проблему с помощью концепции, называемой "Группы сообщений". Хотя это не является частью стандарта JMS, некоторые продукты, связанные с JMS, работают одинаково. Основная идея состоит в том, что вы назначаете каждое сообщение "группе", которая указывает на сообщения, которые связаны и должны быть обработаны по порядку. Затем вы настраиваете его так, чтобы каждая группа доставлялась только одному потребителю. Таким образом, вы получаете балансировку нагрузки между группами, но гарантируете доставку заказа в пределах группы.
Для тех, кто заинтересован в том, чтобы решить эту проблему:
- Использовать шаблон списка получателей EAI
Поскольку вопрос касается JMS, мы можем взглянуть на пример с веб-сайта Apache Camel.
Этот подход отличается от других шаблонов, таких как CBR и Selective Consumer, потому что потребитель не знает, какое сообщение он должен обработать. Позвольте мне привести пример из реальной жизни:
У нас есть система управления заказами (OMS), которая отправляет заказы для обработки ERP. Затем ордер проходит 6 этапов, и каждый из этих шагов публикует событие в очереди Order_queue, информируя о статусе нового ордера. Здесь нет ничего особенного. OMS использует события из этой очереди, но ДОЛЖЕН обрабатывать события каждого Ордера в той же последовательности, в которой они были опубликованы. Скорость сообщений, публикуемых в минуту, намного выше, чем пропускная способность потребителя, поэтому задержка увеличивается со временем.
Требования к решению:
- Потребляйте параллельно, включая столько потребителей, сколько необходимо для поддержания размера очереди в разумных пределах.
- Гарантируйте, что события для каждого Заказа обрабатываются в одном и том же порядке публикации.
Реализация:
На стороне OMS Процесс OMS, отвечающий за отправку заказов в ERP, определяет потребителя, который будет обрабатывать все события определенного заказа, и отправляет имя получателя вместе с заказом. Как этот процесс узнать, каким должен быть Получатель? Ну, вы можете использовать разные подходы, но мы использовали очень простой: Round Robin.
В ERP Поскольку он сохраняет имя Получателя для каждого Заказа, он просто настраивает сообщение, которое будет доставлено нужному Получателю.
На OMS Consumer Мы развернули 4 экземпляра, каждый из которых использует свое имя получателя и одновременно обрабатывает сообщения.
Можно сказать, что мы создали еще одно узкое место: базу данных. Но это не так, поскольку в строке заказа нет параллелизма.
Одним из недостатков является то, что процесс OMS, который отправляет Заказы в ERP, должен хранить информацию о том, сколько получателей работает.
Большинство EIP-фреймворков и ESB имеют настраиваемые средства упорядочения. Если количество объектов не слишком велико, вы можете иметь очередь на объект и повторную последовательность в начале.