Is it possible to use CLIENT_ACKNOWLEDGE in producer side in JMS? Then what does it mean? I mean acknowledging is something in consumer side.
No, message acknowledgement is purely a consumer side concept. When creating a JMS Session you have the choice among several acknowledgment modes. The idea behind message acknowledgement has to do with the concept of guaranteed delivery in message oriented middleware (MOM). In short, when you send a message via a MOM implementation, that message will be persisted (by the producer) until it is sent to a consumer AND the consumer acknowledges its delivery (or until the message expires). In the event that an acknowledgement is not received by the consumer within some reasonable amount of time the message is re-sent by the producer. Each mode impacts message delivery differently.
In AUTO_ACKNOWLEDGE mode, any messages received by consumers through the session will be acknowledged automatically by the consumers underlying JMS runtime upon reception.
In CLIENT_ACKNOWLEDGE mode, each message received by consumers through the session must be explicitly acknowledged. This means that the responsibility of acknowledging a message falls on the application instead of the JMS runtime. Typically the consumer needs to invoke the acknowledge() method on the session after processing the message in the onMessage() method.
There is also a DUPS_OK_ACKNOWLEDGE setting that is similar to AUTO_ACKNOWLEDGE but instead acknowledgements are sent by the JMS implementation lazily, potentially causing duplicate reception of messages.
Typically you would use CLIENT_ACKNOWLEDGE mode when you need to have explicit control over the acknowledgement of messages.
Related
I have a producer send msg to a ActiveMQ broker, and a consumer subscribe from the same topic. I know that the broker can persist the msg, so as soon as the msg reaches the broker, it can be guaranteed available for the consumer. (right?)
But what happen if the network between producer and ActiveMQ broker is broken, in this case is there a way to guarantee the at-least-once sent? like, the producer itself can persist msg before sending to the ActiveMQ broker?
In order for the guarantee to be established the message must reach the broker, if the network is down then the burden is on you to capture the send error and retry the send at a later time. The ActiveMQ client offers no persistent storage for what it sends, you can use the failover transport and the client will retry the send on reconnect but it the application is shutdown and you haven't provided some means of recovery on restart then there isn't anything more the client can do.
I read following quote from ActiveMQ documentation here:
The downside to using synchronous message delivery is that the
producer is more likely to block if there is a slow consumer that he
is dispatching messages to.
But I don't understand how the producers, in general, can be blocked because of slow consumer, because my understanding is that a JMS client (producer) will send a message to a queue of a ActiveMQ instance (broker) and that's it, now producer is free or in other words producer thread which sent the message is free to complete/die. Then there will be some other JMS clients (consumers) listening for that queue, now as soon as message arrives to the broker, broker will send it to the listening consumers.
Now, in all this where producer is dependent upon consumer?
When a producer send a persistent message to the broker the broker must write that message to disk before sending back an acknowledge to the producer to let it know what it's message is safely stored away for later dispatch to a consumer. In the case of a slow consumer the producer might eventually run into a case where the broker has reached a resource limit and cannot store that message either on the Queue in memory or on disk, it all depends on the broker's configuration.
The the producer isn't so much tied to the consumer as it is to the resources on the broker needed to hold the message until it has been consumed.
I have an issue related to java messaging service ...
Problem: suppose my JMS publisher sends me 5 messages... When I receive first two messages my app processes them and acknowledges them... So that it is removed from the topic... Wen I receive 3rd message, because of some problem my app cannot process it and doesn't acknowledge... But 4th and 5th message got processed and acknowledged... But wen I checked the admin console I found out that the 3rd message is also acknowledged...
I want to know how to acknowledge each message individually. Anybody has idea???
Note: I'm using CLIENT_ACKNOWLEDGE mode.
According to JMS specification CLIENT_ACKNOWLEDGE - acknowledging a consumed message automatically acknowledges the receipt of all messages that have been delivered by its session.
Many JMS providers have implemented above specification and hence don't provide acknowledging one message. But some JMS providers (AcitveMQ ??) do implement per message acknowledgement. So you will need to check with your JMS provider if it supports per message acknowledgement feature.
My requirement is that:
I have an IBM MQ which is shared across 20 servers and runs the JMS client. Now there will be a specific message in the queue which is intended for a particular thread. The thread need to use a correlationID to fetch the message from all the messages in the MQ.
When I am using onMessage() it is uncertain which thread will Listen to the message. Suppose server-1 is waiting for the message but server-15 listens it. Server-1 gets eventually timed out even though there was a message intended for the thread in server-1.
Please suggest how we are going to handle this scenario without introducing major performance issue.
Use a MessageSelector on the listener container(s). If the correlationId is in the standard JMSCorrelationID header the selector would be JMSCorrelationID=foo to receive all foo messages.
I'm dealing with a standalone MQ JMS application, our app need to "aware" that client already consumed the message producer put on the queue. Because client app is not responsible by us. So we cannot let them to write something like "msg.acknowledge();" thing on their side (msg.acknowledge() is not the right approach on my condition.). I search the history answer in the stackoverflow. Find following is quite the same what I want:
https://stackoverflow.com/questions/6521117/how-to-guarantee-delivery-of-the-message-in-jms
Do the JMS spec or the various implementations support delivery confirmation of messages?
My question is, is there any other way to archive this in the MQ API or JMS API? I need to do the coding only on the msg produce side, it is can be queue or topic.
Another question is in the JMS the acknowledge mode CLIENT_ACKNOWLEDGE, is that produce irrelevant? I always believe that this mode can block the application when call send() method until the client consume the message and call the msg.acknowledge(), but seems not like that. The produce just exit the app after message be delivered, and the message just store in the queue until client call the acknowledge(). Is that possible let the producer app hang there wait until the message be acknowledged by the client?
If my concept is not right, just correct me, thanks.
The main intention of message queuing is to decouple producer and consumer. Producer does not need to wait for the message to be consumed by the consumer, it can continue it's job. Ideally if producer needs to know if the message has been processed by consumer or not, it should wait for consumer to send a response message on another queue.
Message acknowledgement has nothing to do with producer. Message acknowledgement is the way a consumer tells the messaging provider to remove the message from a queue after the message has been delivered to an application.
There is auto acknowledge where the JMS providers (like MQ JMS), after delivering message to an application, tell the messaging provider to remove the message from queue. Then there is client acknowledge where, after receiving a message, the application explicitly tells the messaging provider to remove message from a queue.
Is there is a reason why the producer has to wait for consumer to receive the message? One way, though not elegant, could be: Once the message is sent, use the message id of the sent message and try to browse for that message. If message is not found, you can assume it has been consumed