I am trying to find a way to load balance requests to a group of similar configuration activemq brokers.
Suppose, i have 3 activemq brokers(A, B, C), each having (say) two queues (X,Y) operating.
Every activemq broker has same queues ie. X & Y.
Every activemq broker queues have a dedicated consumer. which consumes messages only from their respective broker's queue.
Now, I want to load balance requests to my 3 queues load balanced in round-robin. i.e. the 1st request should go to Queue A, then next request to queue B and then next request to queue C and so on.
Any guidance please.
Check out ActiveMQ's Networks of Brokers feature: http://activemq.apache.org/networks-of-brokers.html. I'd use as much of ActiveMQ's built-in functionality as possible before coming up with any custom round-robin code of your own.
Related
Scenario: Two ActiveMQ nodes A, B. No master slave, but peers, with network connectors between them.
A durable topic subscriber is registered with both (as it uses failover and at one point connects to A and at another point connects to B).
Issue: If subscriber is being online against A, a copy of each message is placed in the offload subscription on B.
Question: Is this by design? Can this be configured so that a message is deduped and only sent to the subscriber in one of subscriptions?
Apparently by-design: http://activemq.apache.org/how-do-distributed-queues-work.html
See "Distributed Topics in Store/Forward" where it says:
For topics the above algorithm is followed except, every interested client receives a copy of the message - plus ActiveMQ will check for loops (to avoid a message flowing infinitely around a ring of brokers).
I setup two nodes, A and B. Both have RabbitMQ with the federation plugin installed.
From the Web UI, I can see the "Federation Status" > "State" is "running" on A and B.
On A, I created a queue called "test1".
On B, I can see the "test1" queue (replicated from A).
On A, I added a message.
However, the message does not appear in the replicated queue on B - the message stays on A.
This is the policy I used on A and B:
rabbitmqctl set_policy --apply-to exchanges my-queue "test1" \
'{"federation-upstream-set":"all"}'
So, it's like this: A (upstream) -> B (downstream) and B (upstream) -> A (downstream)
Am I supposed to see messages replicated to both A and B? Did I misconfigure the directions?
However, the message does not appear in the replicated queue on B - the message stays on A.
TL;DR: federated exchange != federated queue.
References:
https://www.rabbitmq.com/federated-exchanges.html
https://www.rabbitmq.com/federated-queues.html
The "How it works" section on federated queues explains:
" The federated queue will only retrieve messages when it has run out of messages locally, it has consumers that need messages, and the upstream queue has "spare" messages that are not being consumed ... "
Whereas the "What does a federated exchange do?" explains:
" ... messages published to the upstream exchanges are copied to the federated exchange, as though they were published directly to it ... "
recap:
if you use a federated queue,
you would need a consumer on the B side that needs messages (pull model?).
if you use a federated exchange,
messages a copied directly (push model?).
Use cases
Redundancy / Backups
Federated exchanges copy messages (max-hops copies) so they can be used for redundancy.
E.g.
here is my data, back it up.
Content distribution network
Federated exchanges copy messages (max-hops copies) so they can be used to distribute content across regions (that's also redundancy btw) provided you configure the topology correctly.
E.g.
hey everybody, please apply this security patch, which you can find at your nearest broker.
Load balancing
Federated queues can be used for load balancing: if a message is available upstream and there is no consumer there to process it, a free consumer downstream is able to receive the message and work on it. Rock on.
E.g.
I'm a computer, and I feel bored, can I help you? Any job you need me to do?
double-whammy
Federated exchange + federated queues = you can distribute the same set of tasks to multiple regions (cluster), and one worker in each cluster can perform the job.
E.g.
It's end of the quarter, I need performance metrics for each region (cluster), each store manager (one node in cluster) will aggregate metrics (inside cluster), and we'll give gift cards to the top 3.
I had two ActiveMQ brokers (A and B) that were configured as store-forward network. They work perfectly to forward messages from A to B when there is a consumer connected on broker B and producer sends messages to A. The problem is that when the consumer is killed and reconnected to A, the queued messages on B (they were forwarded from A) won't forward back to A where the consumer connected to. Even I send new messages to B, all messages were stuck on B until I restart brokers. I have tried to set networkTTL="4" and duplex="true" on the broker network connector, but it doesn't work.
Late answer, but hopefully this will help someone else in the future.
Messages are getting stuck in B because by default AMQ doesn't allow messages to be sent back to a broker to which they have previously been delivered. In the normal case, this prevents messages from going in cycles around mesh-like network topologies without getting delivered, but in the failover case it results in messages stuck on one broker and unable to get to the broker where all the consumers are.
To allow messages to go back to a broker if the current broker is a dead-end because there are no consumers connected to it, you should use replayWhenNoConsumers=true to allow forwarding messages that got stuck on B back to A.
That configuration option, some settings you might want to use in conjunction with it, and some considerations when using it, are described in the "Stuck Messages (version 5.6)" section of http://activemq.apache.org/networks-of-brokers.html, http://tmielke.blogspot.de/2012/03/i-have-messages-on-queue-but-they-dont.html, and https://issues.apache.org/jira/browse/AMQ-4465. Be sure that you can live with the side effects of these changes (e.g. the potential for duplicate message delivery of other messages across your broker-to-broker network connections).
Can you give more information on the configuration of broker A and B, as well as what you are trying to achieve?
It seems to me you could achieve what you want by setting a network of brokers (with A and B), with the producer only connecting to one, the consumer to the other.
The messages will automatically be transmitted to the other broker as long as the other broker has an active subscription to the destination the message was sent to.
I would not recommend changing the networkTTL if you are not sure of the consequences it produces (it tends to lead to unwanted messages loops).
I understand the topic is for broadcasting messages to the clients. But in the ActiveMQ document, it says about load balancing:
Another way of explaining Message Groups is that it provides sticky load balancing of messages across consumers; where the JMSXGroupID is kinda like a HTTP session ID or cookie value and the message broker is acting like a HTTP load balancer.
Here comes what I don't understand.
Is it not broadcasting?
What I want to do is below:
If producer send messages to group A, somehow the broker control the traffic and the messages "physically" should not go to group B.
Is it even possible with Virtual Topic?
VirtualTopics create queues for each topic subscriber and replicates messages to each one, so it is "broadcasting" all messages to all subscribers.
ActiveMQ message groups provide you with an exclusive consumer thread for a given message group (distinct JMSXGroupID). You can't control which consumer picks up each group and the same consumer thread can process multiple groups.
As far as I know, if you set the JMSXGroupID on a message sent to a VirtualTopic, it will arrive in each subscriber's virtual queue. However, if you have multiple threads processing from those queues (maxConcurrentConsumers > 1), then they will be single-threaded per message group, etc.
Overall, if you want certain subscribers to only process a subset of messages sent to a topic, then use message selectors to down select this subset.
I have configured two brokers A and B using networkconnectors.
Is the message order preserved if I am using exclusive consumer (single consumer) or message groups(JMXgroupID)?
In the network of broker documentation I found this:
Total message ordering is not preserved with networks of brokers. Total ordering works with a single consumer but a networkBridge introduces a second consumer. In addition, network bridge consumers forward messages via producer.send(..), so they go from the head of the queue on the forwarding broker to the tail of the queue on the target. If single consumer moves between networked brokers, total order may be preserved if all messages always follow the consumer but this can be difficult to guarantee with large message backlogs.
In single broker message ordering is possible through exclusive consumer. What will happen if I am using network of brokers with exclusive consumers?
Total message ordering in a network of brokers doesn't work - even if you have a single consumer or multiple consumers using the "exclusive consumer" feature.
Consider the following scenario with 2 brokers (let's call these broker-A & broker-B) in a network, 1 consumer (consumer-A), 2 producers (producer-A & producer-B), and 1 queue (queue-A).
producer-A connects to broker-A, sends a message (message-1) to queue-A, and disconnects.
producer-B connects to broker-B, sends a message (message-2) to queue-A, and disconnects.
producer-A reconnects to broker-A, sends a message (message-3) to queue-A, and disconnects.
consumer-A connects to broker-A and receives the messages from queue-A. Even though the messages were sent in order message-1, message-2, message-3 the consumer will actually receive the messages in the order message-1, message-3, message-2 because message-1 and message-3 were sent to broker-A and message-2 was sent to broker-B and had to be moved across the network of brokers to broker-A based on consumer demand.
It's worth noting that one of the main goals of a network of brokers is scalability. However, in order to guarantee messages are consumed in order the messages have to be consumed serially which can drastically reduce performance and would almost certainly nullify any scalability gains provided by the network of brokers. Total message ordering and a network of brokers are fundamentally opposed ideas. If you really want total message ordering you shouldn't use a network of brokers.