Мы пытаемся создать справедливые очереди с помощью ActiveMQ Artemis.
Допустим, компания А отправляет много сообщений для обработки. Теперь компания Б отправляет сообщения. Мы хотим, чтобы сообщения от компании B обрабатывались до того, как будут завершены все ранее поставленные в очередь сообщения компании A. Справедливым, параллельным образом. Таким образом, компании Б не придется ждать А.
Было бы неплохо не создавать отдельные очереди для A и B. Только одну для определенного процесса-потребителя.
Мы использовали Queue-Selector, настраивая потребителей для каждой компании и добавляя реквизит компании в сообщение. Было замечено, что он работает очень хорошо, но мы видим, что под нагрузкой сообщения второй компании задерживаются. Мы подозреваем, что файлы журнала становятся достаточно большими, и брокер не может видеть их все, чтобы отправить потребителю с помощью селектора резервное сообщение.
Так интересно, решил ли кто-нибудь эту проблему с помощью функции ActiveMQ Artemis.
Спасибо!
Селектор очереди не работает.
Основная семантика очереди — «первым пришел — первым обслужен» (т. е. FIFO). Обычно это считается справедливым, поскольку первое сообщение, поступившее в очередь, первым и уйдет. Вы, конечно, можете немного переопределить это, задав разные приоритеты сообщений, но конкретное поведение, которое вы описываете, не поддерживается, и я не уверен, что это можно было бы назвать справедливым.
Даже при использовании селекторов на основе потребителей очередь по-прежнему придерживается семантики FIFO, поэтому неудивительно, что вы все еще видите задержки.
Самое простое решение (которого вы почему-то хотите избежать) — просто использовать разные очереди. Вы можете использовать возможности многоадресной рассылки , фильтрованных очередей и полных имен очередей, чтобы сделать это как можно проще. Например, у вас может быть один адрес, по которому были отправлены все сообщения, и несколько очередей с фильтрами, которые будут собирать сообщения в соответствии со значением свойства, уникальным для компании-отправителя. Соответствующая конфигурация для компаний A и B, использующих свойство с именем company
, будет выглядеть примерно так broker.xml
:
<addresses>
<address name = "allCompanies">
<multicast>
<queue name = "A">
<filter string = "company='A'"/>
</queue>
<queue name = "B">
<filter string = "company='B'"/>
</queue>
</multicast>
</address>
</addresses>
Таким образом, все компании будут отправлять сообщения на адрес allCompanies
. Однако потребители, которым нужны сообщения от одной конкретной компании, будут получать сообщения из определенной очереди компании (т. е. allCompanies::A
или allCompanies::B
).
Это не то же самое, что использовать тему jms с селекторами, верно? Я думаю, что разница в том, что каждый экземпляр потребителя получит сообщение, а это не то, чего мы хотим. Только один экземпляр сообщения может быть использован несколькими потребителями для любой компании. Очередь должна гарантировать это. В документе я видел, что CORE API использует комбинацию многоадресной рассылки и очередей для реализации подписки на темы. Это заманчиво, поскольку мы используем JMS. Кстати, я не вижу примеров использования CORE в примере проекта. Этот ServerLocator пока сложен.
Это похоже на тему JMS с селекторами потребителей, поскольку в результате для каждого потребителя создается фильтрованная очередь многоадресной рассылки. Однако в описанной мной конфигурации несколько потребителей могут совместно использовать каждую очередь, используя полное QQN. Нет необходимости использовать основной API из ваших клиентских приложений. Вы можете использовать JMS-клиент. Просто убедитесь, что вы отправляете в тему JMS allCompanies
, а затем используете очередь JMS для интересующей вас компании (например, allCompanies::A
, allCompanies::B
и т. д.).
Большое спасибо за это решение. Мы беспокоились об управлении всеми очередями, но это упрощает задачу: по-прежнему один адрес. Кроме того, динамический характер конфигурации адресов должен упростить автоматизацию добавления новых компаний!