First, let me explain what I have tried with classic ActiveMQ which worked perfectly for my requirements:
I have few Queues with naming templates and each queue represents a Tenant(customer). The naming pattern is like queue.<<tenant-id>>.event which, here, I used test1 to test5 for simplicity.
Multiple producers are putting messages on these different queues based on which tenants are requesting it.
My ActiveMQ queues look like this in the web console: Queues in the classic ActiveMQ
Then I started the Spring JMS listener with the wildcard to be able to read from all of these queues with one listener. the code is like this:
@JmsListener(destination = "queue.>")
public void receiveMessage(Event event) {
//Process the event message
}
What I have observed which I cannot configure Artemis to do the same is:
- Listening on ActiveMQ Queues with wildcard did not create a new queue(listener Queue)
- Consuming the messages with a wildcard listener would actually reduce the number of pending messages in the actual queues.
- The wildcard listener would actually quite fairly read messages from all queues. It still does respect the FIFO on each queue but would not respect it cross queues. For example, when I put 100 messages in the
queue.test1.eventand only then add 100 messages inqueue.test2.event, then if I start the wildcard listener, it starts to read messages fairly from both queues, although all the messages inqueue.test2.eventqueue are basically added after the 100 messages inqueue.test1.event.
I need features #2 and #3. The first one is just the observation which I think is the root cause of my problem in Artemis.
Now, what happened when I moved to Artemis is: The wildcard pattern is a little different but I did the same scenario. The listener looks like:
@JmsListener(destination = "queue.#")
public void receiveMessage(Event event) {
//Process the event message
}
As you see the wildcard template is changed to queue.# to be able to read from all those queues.
My Artemis queues look like this in the web console: Queues in the Artemis,
My observation on the web console shows I cannot achieve the same here:
- As you see in the picture, the number of
message countin the original queues, in which I put the messages, are still kept, despite only 44 of them are remained for processing(looks at themessage countofqueue.#) and the rest has been already read by the wildcard listener.This can cause a storage issue for me since all of my messages are persisted and I can't play with the message expiry too.
- As you see in the picture, the listener created another Queue named
queue.#which seems Artemis is internally copying the messages from the other ones into it.Not a problem and just an observation.
- It respects the FIFO across all queues, which I guess is because Artemis is doing the copy from the original queues to the wildcard one.
This creates a huge problem for me. Although I still want it to respect the FIFO inside each queue, I also want it to start consuming messages from other queues. Because, if one customer is processing huge tasks, it should not block others to continue theirs.
PS1: I restrict the listeners in both tests to just consume one message at a time to be able to test it properly.
PS2: If you wonder why I don't use classic ActiveMQ if it does exactly what I need, The answer is: Apache will make Artemis its Major version(once it reached a certain level of maturity) in the future and I would like to be aligned with the roadmap.Quote from its website:
Once Artemis reaches a sufficient level of feature parity with the "Classic" code-base it will become the next major version of ActiveMQ
PS3: I am using spring-boot and its starter packages to connect and put/consume messages.
PS4: I am using the default configuration for both solutions and installations.