RabbitMQ work Queue : Starting Consumer after Sender [Java] - java

I am quite new to using RabbitMQ as message queuing protocol.I have written a code for sender and consumer work queue as given in RabbitMQ tutorials.
[Link : http://www.rabbitmq.com/tutorials/tutorial-two-java.html ]
The above thing works fine when we start the consumer before the sender.
But there is an issue if we start the consumer after running the sender.
None of the messages are consumed by those consumers which are started
after running the sender.
After looking into the architecture of RabbitMQ and the AMQP related things,it seems quite difficult.
1] Is it possible,that we start the consumer after sender and the consumer which are started after the sender receives the messages in Queue?
2] If yes.Then how this thing can be done.Is there some technique to do the same?

Yes, it is possible. Make sure that your queue is declared with auto-delete set to false. Once the last consumer unsubscribes if auto-delete is set to true then the queue will be deleted and when your sender pushes messages to it they will be lost. If auto-delete is set to false then the queue will continue to exist after your consumer has unsubscribed and your sender will be able to push messages to the queue without them being lost.
Find more info about queues at http://www.rabbitmq.com/tutorials/amqp-concepts.html#queues

I suppose in the first case(starting consumer first), the consumer properly creates/registers the queue it wants to listen on the RabbitMQ server. So when sender sends it's able to receive it.
In the second case probably what's happening is sender is trying to send to a queue which is not existent/not created and goes to default/dead-letter.
I suggest you can open the RabbitMQ Management console and see whether the queues are created properly.

Related

RabbitMQ Spring AMQP - Message Processing after some time

Using Spring AMQP (Using RabbitMQ as message broker), I am preparing a message and I want my message to consume after sometimes. Till then it can wait in some queue like waiting queue and then moved to our main queue where we have the consumer which is waiting to process the message from main queue.
I got confused whether I should apply dead letter exchange in this scenario and how to apply the dead letter exchange in it is the big question for me.
Any Idea how can we make it work.
P.S > If it is possible without rabbitmq_delayed_message_exchange plugins.
If you don't want to use the delayed exchange plugin, you can send a message to a queue with a time to live (ttl set on the queue or message).
Configure the queue to route expired messages to a dead letter exchange which routes to the final queue.
someExchange -> ttlQueueWithDLX -> DLX -> liveQueue

How to save messages and Topics in Activemq?

I have a Queue and Topic with 2 messages in Activemq.If I restart Activemq.I am losing messages and also Topic.
Even If I restart Activemq,I don't want to lose any messages from any Topicand Queue.Is it possible.
I am using Activemq 5.8.0.
A producer produces the message and send it to the Topic, which ever
consumer is running at that point of time, will receive the message.
If you want consumer which is not up now, but might be running in
future to get this message, you will have to tell the Broker to
persist the message and store the information that this perticular
consumer has not received the message.
If you have working code with-out durable subscriber, you will have to do the following changes.
In the consumer,
1. set the clinetId. Because Topic should know which consumer is yet to receive the message. Or has received the message.
Connection.setClientID(String)
2. Should be creating a durable subscriber for your topic
Connection.createDurableSubscriber()
3. Add your listener to this subscriber.
subscriber.setMessageListener(yourlistener)
4. Once you receive the message, you will have to acknowledge it
This link shows how it is done: But its in c# i guess.
http://myadventuresincoding.wordpress.com/2011/08/16/jms-how-to-setup-a-durablesubscriber-with-a-messagelistener-using-activemq/
Read these links for more info :
http://activemq.apache.org/how-do-durable-queues-and-topics-work.html
http://activemq.apache.org/why-do-i-not-receive-messages-on-my-durable-topic-subscription.html
http://activemq.apache.org/manage-durable-subscribers.html

How to receive acknowledgement in JMS

Here's my scenario. The program is developed with publisher/subscriber methodology. Have two topics (topic1, topic2) in producer and consumer part. I need to get the acknowledgement of the received topic1 from consumer in producer program so that when the acknowledgement status is true, the producer program will have to send the message on topic2.
Had googled links suggesting session.CLIENT_ACKNOWLEDGE in consumer. But I'm in need of the Acknowledgement status to be returned to producer for further process.
JMS specification does not define any API for a publisher to know if a message was consumed by a subscriber or not. A publisher just publishes a message and it is the messaging provider/broker to deliver that message to subscriber. A broker will deliver the message if there is a subscription otherwise that message is discarded.
The session.CLIENT_ACKNOWLEDGE option is one of the way a consumer tells a messaging provider (not producer) to remove the message from it's queue/memory. There are couple of other acknowledgement options as well but all these options are for telling a messaging provider to remove the message but not telling a producer.
If producer requires an acknowledgement from a consumer, then consumer will have to publish an acknowledgement message on another topic and producer subscribes to that topic to receive those acknowledgements. For example:
Producer publishes on TOPIC1
Producer subscribes to TOPIC1/ACKS
Consumer subscribes to TOPIC1
After receiving a message
Consumer publishes an acknowledgement message to TOPIC1/ACKS
Producer will receive the acknowledgement message.
It can then publish on TOPIC2
You must note that there can be multiple acknowledgement messages as there can be more than one subscribers on TOPIC1.
If your program contains only one message producer, you can create a Queue in the message consumer and let the producer subscribe to that Queue. In the Queue mode, it's point-to-point. So the message will only be delivered from the consumer to the producer.
Alternatively, you can also use setJMSReplyTo method to specify the Queue you want the consumer reply to when it receives the message from the producer. This way you don't need to create the Queue explicitly in the consumer but you can create the Queue in the producer as well. But you still need to let the producer listen to that Queue to received the acknowledgement.

MDB not listening after startup

I have a Message Producer running on one JVM that puts in messages in a JMS Queue .I have a Message Consumer which implements Message-Driven-Bean and MessageListener interface that listens to this queue.This Message consumer is on a different JVM.
The producer puts in messages in the queue properly.But the MDB is not able to pop out messages from queue.The weird thing is that when I restart my Message Consumer , all the messages in the queue are popped out by the Message Consumer at once.After this,no matter how many messages producer puts in the queue ,the Message Consumer does not pop them out.
What could be the reason??
The application server I am using is JBOSS4.0.5.GA.
Thanks
Please provide more details. From what you have provided:
is your consumer running and waiting for messages ? (inside some sort of while loop or a blocking call)
you can set prefetch size for your consumer to be 1 in your jms connection settings so that it fetches only 1 (or whatever number) message from the queue.

How to send Message to particular Receiver using JMS Queue

Is it possible to send message to particular receiver using JMS Queue(HornetQ)?
Among so many receivers, I want certain message to be received by receiver which
are running on Linux OS.
Every suggestion is appriciated.
Thanks.
You can set a message property using Message.setObjectProperty(String, Object) and then have your consumers select the messages they are interested in using Session.createConsumer(Destination, String)
Sender example:
Message message = session.createMessage();
message.setObjectProperty("OS", "LINUX");
producer.send(message);
Receiver example:
MessageConsumer consumer = session.createConsumer(destination, "OS = 'LINUX'");
//Use consumer to receive messages.
The receiver in the example will ignore (they will go to some other receiver) all messages that do not match the selector. In this case all message where the 'OS' property is not 'LINUX' will be ignored by this consumer.
You can set properties of JMS message: http://download.oracle.com/javaee/1.4/api/javax/jms/TextMessage.html and filter messages at client side.
For example,
message.setStringProperty("TARGET_OS", "LINUX") - at sender
http://www.mkyong.com/java/how-to-detect-os-in-java-systemgetpropertyosname/ - detect OS at receivers and filter messages with correct TARGET_OS property
You can use JMS selectors on the consumer side to look for messages that fit specific criteria.
Not sure if I am missing something, you could keep things simple by having multiple queues - specific to each platform, then the linux based consumers can listen to the linux specific queue alone. Now your challenge probably will be to route the messages to the appropriate queue from the producer side, that should be fairly easy if the routing is based on some attribute of the message?

Categories

Resources