0
votes

I'm using activemq (pretty new to me) and I have one producer and several consumers.

Thing is, I want to address messages for specific consumers. I read about selectors but also read that it is a bad practice to use and also read about some alternatives.

The alternative sounds good for me, but I'm not sure how I can create these queues for each and every one of my slaves. Each of my slaves has an ID (uuid) that I can use when I'm creating the listener - like this:

<jms:listener-container
        container-type="default"
        connection-factory="jmsConnectionFactory"
        acknowledge="auto">
    <jms:listener destination="slave.tasks.${slave.id}" ref="jmsActivityListener" method="onMessage" />
</jms:listener-container>

This requires the slave.properties file to contain the following entry:

slave.id=XXXXXXX

My questions are:

1) Is that the way to do it (defining a queue per consumer)?

2) How can I generate this salve.id value (I don't want the user to fill it as it has to be unique)?

Thanks

1

1 Answers

0
votes

Virtual Topics to the rescue

The idea behind virtual topics is that producers send to a topic in the usual JMS way. Consumers can continue to use the Topic semantics in the JMS specification. However if the topic is virtual, consumer can consume from a physical queue for a logical topic subscription, allowing many consumers to be running on many machines & threads to load balance the load. E.g., let's say we have a topic called VirtualTopic.Orders. (Where the prefix VirtualTopic. indicates its a virtual topic). And we logically want to send orders to systems A and B. Now with regular durable topics we'd create a JMS consumer for clientID_A and "A" along with clientID_B and "B". With virtual topics we can just go right ahead and consume to queue Consumer.A.VirtualTopic.Orders to be a consumer for system A or consume to Consumer.B.VirtualTopic.Orders to be a consumer for system B. We can now have a pool of consumers for each system which then compete for messages for systems A or B such that all the messages for system A are processed exactly once and similarly for system B.

http://activemq.apache.org/virtual-destinations.html

<jms:listener-container
        container-type="default"
        connection-factory="jmsConnectionFactory"
        acknowledge="auto">
    <jms:listener destination="Consumer.#{T(java.lang.System).currentTimeMillis()}.VirtualTopic.tasks" ref="jmsActivityListener" method="onMessage" />
</jms:listener-container>

your producer can send messages to topic "VirtualTopic.tasks" and these messages will be sent to all Consumer.*.VirtualTopic.tasks queues