I want to understand a thing: When a durable subscriber is activated on a topic, in add on this topic there is another subscriber (mdb). Is possible that the durable subscriber take the messages and don't provide it to the MDB?
Thanks a lot..
When a message is sent to a topic, by intent there's a separation between the publisher and the consumers.
Although there are ways you can create transactional delivery around sending to all consumers, there's no way a consumer can take a message and prevent other consumers from receiving a message as well.
Related
I have a topic. I have 10 consumers subscribed for it. As per my understanding, a message will be removed from
topic when all consumers have received it. Right? Once it is removed, any further subscriber
will not be notified for that specific message. I could not confirm this in the JMS specification anywhere.
A broker (in your case Active MQ) will deliver a publication to all active subscribers, both durable and non-durable (meaning consumer applications which are running when a publication was made on a topic and consuming messages and any durable subscribers which are not active). The broker will then discard the publication. If there are no active subscribers or durable subscribers for a topic, the broker will discard the publication immediately. It will not wait for any subscribers to become active. The only exception is in the case of "Retained Publication" option being exercised, where the broker will cache a publication and deliver to consumers who may arrive later. But note that broker will not wait for all consumers to receive publication before removing it from a topic. I would say there is nothing like 'removing from topic'.
Hope I am clear.
Only active subscribers will get your message in that case, after that your message is removed.
If you want to send your message also to inactive subscribers you can configure durable subscription.
I am begining to implement an ActiveMQ based messaging service to send worker tasks to various servers, however I am noticing that in the default mode, if no one is "listening" to a producer's topic, any message from that producer will be lost.
I.e.,
If Producer Senders Message with a live broker
But No Consumer is there to listen
Message goes no where
I would like instead for the Broker to hold on to messages until at least one listener receives it.
I am trying a couple ways of implementing this, but not sure on the most optimal/right way way:
Implement a Message Acknowledgement feature
(Caveat to this is I need the producer to wait on its listener after every message which seems very, very clunky and last resort...)
Implement the Session Transaction
(I am having trouble with this one, it sounds like the right thing to use here because of the word transaction, but I think it has more to do with the producer-broker interaction, not the producer-consumer)
Ideally, there is a mode to send a (or a set of) messages, and after sending a Boolean is returned stating if the message(s) were listened by at least one consumer.
Transactions and acknowlegdement conflict somehow with the general idea of a JMS topic.
Just use a queue instead of a topic. Access this queue using CLIENT_ACKNOWLEDGE or a transacted session. A worker task is to be processed by one worker only anyway, so the queue solves another problem.
If there was a special reason to use topics, you could consider a message driven bean (MDB) on the same host like the JMS provider (you could achieve this by using JBoss with its integrated HornetQ for example), but this is still not really correct.
Another possibility is to have both a topic and a queue. The latter is only for guaranteed delivery of each message.
This isn't really a typical messaging pattern. Typically, you have one receiver and a durable queue or multiple receivers with durable subscriptions to a topic. in either situation, each receiver will always receive the message. i don't really understand a use case where "at least one" receiver should receive it.
and yes, transactions only deal with the interactions between client and broker, not between client and eventual receiver(s).
I am new to JMS. I have started with "hello world" where I am publishing the message from java application on Topic and
listening it from client (node.js Javascript). I have gone through this wikipedia entry, but I have some questions based on my previous theoretical understanding.
As per my understanding, point-to-point is the queue implementation where there can be at most one consumer subscribed on queue and can
be consumed by that only. Neither producer nor the consumer knows about each other. Queue is hosted on message brokers in my case Apache ActiveMQ. Queue can be created by producer before publishing the message (or it can be created from console in advance).
In case of publish/subscribe model, it's almost same as point-to-point except the fact we use Topic instead of queue. In this model there can be more than more consumer on the topic. Once the message is published, all the subscribers will be notified. Now if any of the subscriber, send the acknowledgment for the published message, message will taken as consumed and it will no longer be available for new subscriber?
Point to Point means message(s) is sent from one application(producer or sender) to another application(consumer/receiver) via a queue. There can be more than one consumer listening on a queue but only one of them will be get the message. Hence it is Point to Point or One to One.
On the other hand Publish/Subscribe is another messaging model where a message(or publication as it is commonly called) is sent to multiple consumers(or subscribers) through a topic. The topic is the link between publisher and subscriber. The subscribers may or may not acknowledge the published message. Implementations like JMS acknowledge the message the messaging providers but not the sender of the message. Publications will be received by all subscribers, durable and non-durable. Any new subscribers on the same topic will not get the publication unless it is a Retained publication.
I would recommend you to read further on,
Durable subscription
Non-durable subscription
Retained publication
I am struggling to understand Durable subscription. I understand that when a Listener registers itself as a Durable Subscriber to a Topic, it tells JMS - "Hey, I am durable subscriber, from now onwards you need to store all the messages in Topic if I am not there and pass me those messages when I come back"
Now, if that's the case, why can't two subscribers ask for this durable subscription?
Am I missing something?
Quoting from the Java EE tutorial
A durable subscriber registers a durable subscription by specifying a
unique identity that is retained by the JMS provider. Subsequent
subscriber objects that have the same identity resume the subscription
in the state in which it was left by the preceding subscriber. If a
durable subscription has no active subscriber, the JMS provider
retains the subscription’s messages until they are received by the
subscription or until they expire.
To make durable subscriptions work for multiple subscribers on 1 durable subscription the broker would have to store each individual message from the creation of the topic (by the first-ever subscriber) until its expiry, ie potentially forever if no message TTL is specified, because at any point in time a new subscriber can pop in and claim all the messages it "missed" (that is, all messages since the subscription was created). That's just not feasible.
I may be missing the point here, but I can't see how having multiple simultaneous subscribers sharing a subscription would be more practical than defining two separate subscriptions?
The understanding of Duplicate Durable Subscription is incorrect.
Durable subscription does not mean that no multiple subscribers can subscribe. It means no One subscriber can have two different identifiers for durable.
I have a durable consumer on a JMS topic. I set the client ID, I can see that it's listed on the queue as a durable consumer.
When I roll out code the server is restarted but I want to queue up the messages that I'm missing while I restart (hence durable). What is the correct way to cleanly shutdown a message consumer so that you close it but still have the queue know to buffer the messages for you
destination = session.createTopic("beacons");
messageConsumer = session.createDurableSubscriber(destination, clientID);
is this the correct way? or will this tell the queue that you no longer want messages delivered when you re-connect?
messageConsumer.close
in a nutshell I'm looking to be able to restart my service without losing messages from the topic I'm subscribed to, thanks!
AFAIK, close() will simply shutdown that consumer. In order to delete the subscription you need to unsubscribe() from it (a method on Session). You should test this with your chosen JMS provider however in order to be sure they implemented the JMS spec the way it was intended! :)