Как заставить подключение ActiveMQ случайным образом выбрать брокера для нового потребителя?

Я использую следующий URL для создания ActiveMQConnactionFactory:

failover:(tcp://server1:port,tcp://server2:port,tcp://server2:port)

Что я хочу сделать, так это создать несколько потребителей сообщений из этой сети брокеров. Следующий код не является реальным кодом, но он помогает понять, как я это делаю:

ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("BROKER_URL");
connection = connectionFactory.createConnection();
connection.start();

for (int i=0; i<10; i++) {
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Destination queue = consumerSession.createQueue("QUEUE_NAME");
consumer = consumerSession.createConsumer(queue);
consumer.setMessageListener(new MessageListener());
}

Проблема в том, что все потребители будут подключены к одному случайно выбранному брокеру. Но я хочу, чтобы они были сбалансированы по сети брокеров.

Я считаю, что это можно сделать, создав несколько соединений с фабрикой.

Но каковы лучшие практики для этого? И это хорошая вещь, которую я хочу?:)

1 ответ

На самом деле, потребитель не будет связан со случайно выбранным брокером.

Соединение - это часть, которая соединяется с брокером. С предоставленной вами строкой соединения у вас будет ОДНО соединение, связанное с ОДНОМ случайно выбранным брокером. У всех потребителей есть свои собственные сеансы, но они будут использовать одно и то же ОДНО соединение с этим ОДНЫМ брокером.

Единственный известный мне параметр - вы можете отключить случайное поведение протокола аварийного переключения, установив ?randomize=false в строке подключения. Это будет означать, что ваше соединение сначала попробует сначала, потом второе, потом третье и т. Д.

Но для достижения вашего требования. Я бы заставил каждого потребителя иметь свою собственную связь. Это, вместе с функцией рандомизации в протоколе переключения при отказе, должно сбалансировать нагрузку потребителей; но не по-настоящему, там нет никакого интеллекта, он просто "рандомизирует" брокера, к которому он подключается.

Это значит, я бы сделал следующее (из вашего кода)

ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory("BROKER_URL");

for (int i=0; i<10; i++) {

connection = connectionFactory.createConnection();
connection.start();
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
Destination queue = consumerSession.createQueue("QUEUE_NAME");
consumer = consumerSession.createConsumer(queue);
consumer.setMessageListener(new MessageListener());

}

Таким образом, у каждого потребителя будет свое собственное соединение с "брокером" вашей строки аварийного соединения.

ОБНОВЛЕНО ПОСЛЕ ИЗМЕНЕНИЯ ВОПРОСА:

Если вы хотите, чтобы ActiveMQ случайным образом выбирал брокера для каждого потребителя, вышеупомянутое решение - это путь.

Лучше всего размещать своих потребителей и производителей как можно ближе друг к другу. Для этого я бы рекомендовал снизить приоритет потребителя сети, чтобы местный потребитель и производитель имели наивысший приоритет. Только когда локальный потребитель не находится в режиме ожидания, он может распространяться дальше по сети другим потребителям.

В дополнение к этому, будет хорошей идеей, если операция на стороне потребителя выполняется долго, чтобы установить более низкое значение предварительной выборки, чтобы сообщения сбалансировали нагрузку по сети брокеров вместо того, чтобы один потребитель захватывал 1000 сообщений, в то время как другие потребители простаивают.

Другие вопросы по тегам