I have a JMS ( ACTIVEMQ ) subscriber(asynchronous) that is polling a topic to receive the message from the JMS provider. The provider is putting an object message into the topic every 5 sec and that subscriber is receiving it as usual.Now when the subscriber terminates, the publisher still continuous to put the messages into the topic. so i want to know how can i handle the program termination of subscriber( i,e i want to know how to handle or what method is called when the subscriber terminates). when the subscriber shuts , the provider keeps on putting the messages into the topic . The provider is running on the server and subscriber is running on the client.
please help :)
Advisory Messages is probably what you are looking for. I have not implemented them myself, but I've read it is possible. You should be looking at the consumerCount
Cheers, Eugene.
Related
I am using Nifi to get data from IBM MQ. It is working fine. My question is once the message is read from an MQ queue, does it get deleted from the queue? How to just read messages from the queue without deleting them from the queue?
My question is once the message is read from an MQ queue, does it get
deleted from the queue?
Yes, that is the default behavior.
How to just read messages from the queue without deleting them from
the queue?
You use the option: MQGMO_BROWSE_FIRST followed by MQGMO_BROWSE_NEXT on the MQGET API calls.
You can also open the queue for browse only. i.e. MQOO_BROWSE option for MQOPEN API call.
It sounds as if you would like to use a "publish/subscribe" model rather than a "point-to-point" model.
From ActiveMQ:
Topics In JMS a Topic implements publish and subscribe semantics. When
you publish a message it goes to all the subscribers who are
interested - so zero to many subscribers will receive a copy of the
message. Only subscribers who had an active subscription at the time
the broker receives the message will get a copy of the message.
Queues A JMS Queue implements load balancer semantics. A single
message will be received by exactly one consumer. If there are no
consumers available at the time the message is sent it will be kept
until a consumer is available that can process the message. If a
consumer receives a message and does not acknowledge it before closing
then the message will be redelivered to another consumer. A queue can
have many consumers with messages load balanced across the available
consumers.
If you have a queue, when a consumer consumes that message, it is removed from the queue so that the next consumer consumes the next message. With a topic, multiple consumers can be subscribed to that topic and retrieve the same message without being exclusive.
If neither of these work for you, I'm not sure what semantics you're looking for -- a "queue" which doesn't delete the message when it is consumed will never let a consumer access any but the first message.
How can I get all messages from a JMS topic in Tibco?
I know that I can use a topic subscriber, but it wouldn't fit exactly my needs. I want to start a process only once a day that will read all messages from a topic and process them. I cannot have both a timer and a topic subscriber in the same process.
I tried with "Wait for JMS Topic Message", but it seems that it gets only one message, no matter how many I have in the topic.
I would try going a different direction. You could implement this using 2 separate processes.
One process, a topic subscriber (with a durable) which receives all messages. This process starter should be disabled by default (so the listener is not active).
The second process is a timer, which will activate the first process through Hawk (Engine Command). So every time the subscriber gets activated, it will start processing events.
The problematic part here is the deactivation of the topic subscriber after it is done. For that you need a separate logic, when to deactivate the subscriber. This could also be done by a separate timer or some Hawk Rule which fires, when the subscriber has no more messages.
I think the best solution will be to bridge the JMS topic to a queue and use the "JMS Queue Receiver" activity at the start of your process.
Once you start the instance once a day, it will connect and process all the messages in the queue.
A much more natural solution (if it can be implemented) is to just implement a Topic Subscriber (or a Queue subscriber if the Topic is bridged to a Queue) and let the BusinessWorks Engine spawn Job instances whenever a message gets published.
This allows to spread the workload much more evenly than to get all the messages from either a Topic or a Queue.
I am still learning about this activemq and jms stuff.
I already tried some example and now I can produce and consuming message from the queue/topic.
Now I have a problem, when my client/consumer lost the connection, the message in queue/topic still send out that message, that message become lost and not kept in the queue/topic. So my question is how I can keep that failed message and how to make the broker resend that message again?
thanks
You are mixing up terminology a bit.
Queues will hold messages until consumed or the broker is restarted, unless the message has been marked as persistent, in which case they will stick around even after a broker restart.
Topics only deliver the current message to any current subscriber. However there are several methods you can use to persist messages published to a topic:
Durable subscribers.
Virtual Destinations .
Virtual Topics tend to be popular for many reasons over durable subscribers, but it really depends on the use-case.
How you create a durable subscriber depends on what you are using to create the subscriber (Spring, POJO, some other API?). All methods will at some point call the Session.createDurableSubscriber method, but I suggest reading up on how they behave before choosing this over Virtual Topic or Composite Queues.
The thing which you are looking for might be Durable subscription
You can find documentation for same at http://activemq.apache.org/how-do-durable-queues-and-topics-work.html
Let's suppose I have several subscribers consuming from a topic. After a message has been delivered to all the subscribers I'd like to trigger a job that would use this message in input.
So the easy way to do that would be to move messages that have been succesfully delivered to all the sucscribers to a queue from which my job would consume messages.
Is it part of JMS?
Is there any message broker able to do that directly?
If not is there a simple solution to solve this problem?
You should be able to do this using activemq's advisories.
See here for more about advisory messages: http://activemq.apache.org/advisory-message.html
So what you want to do, for the topic in question, is track:
the number of consumers
when a message is dispatched to them
when the message has been ack'd by each of the consumers
to get the number of consumers, listen to the "ActiveMQ.Advisory.Consumer.Topic." advisory topic
to get when a message is dispatched, listen to the "ActiveMQ.Advisory.MessageDelivered.Topic."
to get when a message has been ack'd, listen to "ActiveMQ.Advisory.MessageConsumed.Topic."
you could easily use Apache Camel to help out with this (listening to the topics) and aggregating whether or not all consumers have processed (ack'd) the message.. then that could kick off your further processing..
You could just create another durable subscription to route the message from the topic to queue directly. From that queue your job can consume messages. This is much easier than creating a trigger to route the messages to a queue.
So the easy way to do that would be to move messages that have been
succesfully delivered to all the sucscribers to a queue from which my
job would consume messages. Is it part of JMS?
No, this is not part of JMS specification.
I used the Subscriber SYSTEM.JMS.D.SUBSCRIBER.QUEUE and Client ID as setClientID("USER1") and used topicSubscriber = topicSession.createDurableSubscriber(topic,"SUB1");
The topicSubscriber is created and while trying to receive using this topicSubscriber.receive(); , it is not receiving the messages from topic , but there are messages in topic.
Can any one say why its not receiving messages and whether i need to chek any queue configurations.
Any help is appreciated.
Thanks in advance.
I already had topicConnection.Start() in my coding , also i checked in TopicSession there is no Start() Method.
The same code with Non durable subscriber method topicSession.createSubscriber(topic); is working , but for durable it is not working.
Thanks
Sorry, yes I meant topicConnection.Start(). It was worth a check.
I got the answer for durable subscriber not working ,
My queue depth has reached the max queue depth , so the subscriber is not able to subscribe the message.
Eg . my max queue depth for queue SYSTEM.JMS.D.SUBSCRIBER.QUEUE is set to 100 , and if we check our current queue depth and if it reaches 100 the subscriber will not work.
As an alternative way iam trying to create with Temporary Topic , here iam getting an error while creating the durable subscriber topicSession.createDurableSubscriber(topic,"SUB1");
JMS Exception :: javax.jms.InvalidDestinationException: MQJMS0003:
Destination not understood or no longer valid
Can anyone help to solve this error.
Thanks in Advance.
The problem seems to be how you are using SYSTEM.JMS.D.SUBSCRIBER.QUEUE. You appear to be directing messages and subscribers to this queue as the destination for a durable subscription. IBM MQ uses that queue to manage durable subscriptions.
As a general rule, queues whose names begin with SYSTEM are for internal system use by MQ. Some of them, such as SYSTEM.ADMIN.*.EVENT are OK to get messages from but you would not use these as a subscription destination for unrelated messages either.
Many tutorials use SYSTEM.DEFAULT.LOCAL.QUEUE as a destination for messages but this is only because the queue is known to exist on all versions of MQ and MQ uses only the definition of the queue and never the content of that queue. It is easier for the tutorial writer (and IBM is just as guilty here) to point at SYSTEM.DEFAULT.LOCAL.QUEUE then to walk the student through the need for and means to create their own queue. So although best practices suggest it should not be an exception to the "do not use SYSTEM objects" rule, common usage makes SYSTEM.DEFAULT.LOCAL.QUEUE the de facto exception.
The other exceptions are, of course, the command queues for MQ, MFT and IIB. These are also names SYSTEM.* but are designed for users to communicate with the software listening on the queue.
Note that all the exceptions "do not use SYSTEM objects" rule are interfaces between applications and MQ system resources. The event queues are MQ sending information to the user. The command queues are the user sending information to the system components. A subscription is neither of these categories. A destination for a subscription is considered an application-owned object, even when the system manages it on behalf of the subscriber.
When you want a durable subscription, either let the system assign a permanent queue and use that, or else pre-define a queue (that is not named SYSTEM.*) and use that. Whatever else you do, please do NOT try to hijack MQ's internal system queues for application-level purposes.