Consume messages from queue thru topic subscriptions
We have a publisher publishing messages to topics which are then spooled in a durable queue [endpoint] for guaranteed delivery, with several topic subscriptions for various subscribers.
In our tests, the subscriber application acknowledgements do not seem to have any effect on the messages persisted in the queue; only a message TTL causes a message to expire and be removed from the queue.
Do subscriber application acknowledgements after receiving a message thru the topic subscriptions result in the message being removed from the queue, or are they only used for guaranteed delivery (so the broker can resend the message to an online subscriber if no acknowledgement was provided by them)?
In P2P, that would make sense where clients would consume messages off of the queue, but in a pub-sub setup like this, when are the messages removed from the queue, if ever — after all of the online subscribers have acknowledged receipt, or are the messages only removed if a TTL is set on the message and enabled on the broker?
Hi @mystarrocks, there are two different ways to receive messages sent to a topic:
1. Through a subscription;
2. Through a queue which has a subscription.
You'll only consume messages off a queue if your application is bound to the queue and consuming messages from it. In the API, you'll need to create a flow bound to the queue.
A simple test is to publish a message when your consuming application is not connected. Then connect your consumer. Do you see the published message? If you don't, you haven't connected to your queues.1
Note that having your client app subscribing directly to the topic means that you are receiving Direct quality-of-service messages. No retransmission, possibility of loss, etc. If you want fully persistent Guaranteed delivery, then the publisher sends the message to a topic with
DeliveryMode== PERSISTENT, and the consumer is bound to a queue that has the appropriate topic subscription.1
edited January 2022 #4
Thanks for your response, @TomF. You're right, our consumers are receiving messages thru a subscription, not thru a queue that has a subscription, which explains why the messages are only received by the subscribers online at the time, and never removed from the queue. This probably also explains why messages sent as PERSISTENT by the publisher are received as DIRECT (message demotion?).
So flows are how subscribers can consume messages off of a queue with subscription.
Our queue is an exclusive one, so there can only be one active flow (i.e one active consumer receiving messages via subscription on a queue) at any given time. If an active flow (the first consumer to establish a flow with the queue) were to consume messages off of the queue, then other subscribers won't get to receive those messages, correct? Even if it weren't exclusive, our subscribers aren't the same application, so we would like all of them to receive their own copy of the messages.
How do we then ensure messages are received by all the subscribers (may be online or offline at the time of queueing) before they are removed from the queue?
Without a registry of all the subscribers, it sounds like this may never be possible, but that's what we're trying to achieve if possible — all subscribers receive all messages sent by the publisher even if they were offline when they were published/spooled, without the queue disk usage exceeding the maximum spool size. That is why I was wondering if TTL is the only way to achieve something like this. Or, perhaps apps could use their own queue for persistence?0
Oops, I don't know what happened — I posted a comment, but it's gone now.
Anyway, you're right, @TomF — our subscribers receive message thru topic subscriptions, not thru queues with subscriptions, which explains why messages are not removed from the queue. It probably also explains why PERSISTENT messages published by the publisher are received as DIRECT (message demotion?)
So flows are how we can have messages consumed off of the queue... thanks for the pointer! Our queue is exclusive, but even if it were non-exclusive, only the first consumer to connect (i.e active flow consumer) will receive the messages and the other subscribers won't, yes?
The thing is, our subscribers are not part of the same app but are different apps within the same space so they chose to use a single queue, but perhaps they should have one queue per app to have the messages persisted in the respective queues so that one subscriber with an active flow from app1 does not make the messages unavailable for a subscriber from app2, correct?
Again, thank you for your pointers, @TomF and @Aaron - appreciated!0
Ah ha! Yes, that's exactly why you're sending PERSISTENT and getting DIRECT - the topic subscription is causing message demotion. It's always worth checking this, because in this situation you may think you're getting guaranteed but you're not and so may miss messages.
Regarding non-exclusive vs exclusive: no. If the queue is exclusive, only the first flow to bind will get messages. If the queue is non-exclusive, all queues bound will get messages, distributed in a round-robin way.
In general, it's best practice that each seprate app should have its own queue. That way it "manages" that queue and the messages on it. So yes, app1 should have a queue for itself, as should app2.1