For IBM MQ it is possible to use MQGET to browse messages on a queue (https://www.ibm.com/docs/en/ibm-mq/9.2?topic=queue-browsing-messages) or just do a 'normal' MQGET (https://www.ibm.com/docs/en/ibm-mq/9.2?topic=queue-getting-messages-from-using-mqget-call)
I cannot find any differences in what a browse does (except using a cursor) and a normal get does, in terms of what content is being retrieved.
Am I missing something here?
In general a normal get is destructive and the message is permanently removed from the queue, a browse is not deductive and does not remove the message from the queue. The message content returned is the same in either case.
There are three basic situations:
A get with the browse option does not remove the message from the queue, it is still available for other consumers to get or browse from the queue.
A normal get outside of a unit of work will remove the message from the queue, it will not be available for other consumers to get or browse from the queue.
A normal get inside of a unit of work will make the message unavailable for other consumers to get or browse from the queue.
If the unit of work is committed the message will be removed from the queue, it will not be available for other consumers to get or browse from the queue.
If the unit of work is backed out the message will be available again for other consumers to get or browse from the queue.
Related
I have several jobs that each have multiple messages queued.
The messages for each job are randomly interleaved.
If a user decides to cancel a job I want to remove all the messages that are part of that job from the queue.
I have been able to use browse()to find all the messages to remove but haven't been able to figure out how to remove them.
I tried getting rid of them by using receiveSelected() but it just hangs.
(I am using JmsTemplate)
JMS does not define administration type functions, such as deleting a message from the queue.
The programmatic way is to consume the message. Alternatively, there are messaging management tools that allow you to do this without programming.
There is no any JMS API to remove message. However seems you can invoke purge removeMessage or other operation as per your requirement on MBean org.apache.activemq:type=Broker,brokerName=amq,destinationType=Queue,destinationName=testQ to delete messages.
You are on the right track. Consuming those messages using a selector is the way to go - such as with JmsTemplate receiveSelected.
If it "hangs", it likely means you have no matching messages on the queue. Can you identify your messages on some Property, such as JMSType or other StringProperty? Make sure you can and supply a JMS Selector.
I.e. if your jobs are initiated by user X, then set some property such as "initiatingUser" to "x". Then to consume all messages, use the selector initiatingUser='X'.
Is it possible to keep a history of messages (with message content would be perfect) that have already been retrieved and are no longer on a queue?
In the application I can see when the sender attempts to put the message in the queue and when the receiver attempts to pick the messages up, but I'd like to see when the message really arrived into the queue and when the messages were really received.
Does MQ Explorer have this function? How would I use it?
What you are looking for is a message tracking/auditing software for IBM MQ. You can find a list of what is available here.
It is possible to use an API exit to make copies of messages in a queue or to audit both PUT and GET operations.
It is also possible to put messages to a topic, then create as many administrative subscriptions to destination queues as required. Something can then GET and log messages from one of those destination queues. The problem with this is that MQ changes the message ID between publication and consumption whereas in a queue it remains static.
There is no native MQ function to capture messages. It's possible to use linear logs and later scrape the logs but these do not necessarily capture all messages due to optimization. (A message PUT to a waiting getter outside of syncpoint for example.) However there is at least one commercial product to scrape linear transaction logs to audit message activity.
The philosophy of MQ in general is that it is the delivery mechanism and deals with envelope data to route and deliver but does not deal with payload data. WAS, IIB and other broker/transformation engines are where IBM has put all of the functions that deal with message payloads.
I have got started with ActiveMQ and able to move forward, but I am not able to figure out how I can view all messages that are sent to a particular queue.
I can see the message in the queue as long as it is not consumed by a consumer but as soon as it is consumed by a consumer, I can no longer see the message in the queue.
In my project I used to use "MQJ Explorer" and connect with a queue manager and there I could view all the messages that were sent to a particular queue, so I am expecting similar thing with ActiveMQ.
I know while sending I can have the message marked as "persistent" but still it will be there in the queue only till it is not consumed, once it is consumed I cannot see it any more.
Please let me know if things work differently with ActiveMQ.
The Queue holds messages until they are consumed at which point they are discarded. So you cannot browse all messages that were sent to the queue and then consumed. The only solution to this would be to use a Camel route or similar to mirror the Queue to some other Audit type Queue but you'd need to use a lot of care as this could easily lead to filling the message store as the mirrored messages will continue to grow and take space unless they are purged periodically.
The logic flow is like this
A message is sent to an input queue
A ProcessorMDB's onMessage() is invoked. Within this method several operations/validations are done
In case of a poison message(msg that application code cannot handle) a RuntimeException is thrown.
This should rollback the transaction. We are seeing evidence in the log file.
There is a backout threshold defined with a backout queue name
once threshold is reached, the message is sent to backout queue
But immediately it starts going back and forth between the input queue and backout queue.
We are using MQMON tool to observe this weird behavior. It continues for ever almost even after the app server(where MDB is running) is shutdown.
We are using Weblogic 10.3.1 and WebSphere MQ 6.02
Any help will be much appreciated, looks like we are running out of ideas.
This sounds like a syncpoint issue. If the QMgr were to issue a COMMIT when a message is requeued inside of a unit of work it would affect all messages under syncpoint inside of that thread. This would cause serious problems if an application had performed several PUT or GET calls prior to hitting the poison message. Rather than issue a COMMIT outside of the program's control, the QMgr just leaves the message on the backout queue inside the unit of work and waits for the program to issue the COMMIT. This can lead to some unexpected behavior such as what you are seeing where a message lands back on the input queue.
If another message is in the queue behind the "bad" one and it is processed successfully by the same thread, everything works out perfectly. The app issues a COMMIT on the new message and this also affects the poison message on the Backout Queue. However if the thread were to exit uncleanly (without an explicit disconnect or COMMIT) then the transaction is rolled back and the poison message is returned to the input queue.
The usual way of dealing with this is that the next good message (or batch of messages if transactions are batched) in the input queue will force the COMMIT. However in some cases where the owning thread gets no new work (perhaps it was performing a GET by Correlation ID) there is nothing to push the bad message through. In these cases, it is important to make sure that the application issues a COMMIT before ending. One way to do this is to write the code to perform the GET by CORRELID with a wait interval. If the wait interval expires, the application would get a return code of 2033 and then issue a COMMIT before closing the thread. If the reply message is legitimately late for whatever reason, the COMMIT will have no effect. But if the message arrived and had been backed out and requeued, the COMMIT will cause it to stay in the Backout Queue.
One way to see exactly what is going on is to run a trace against the queue in question. You can use the built-in trace function - strmqtrc - which has a few more options in V7 than does the V6 version. However if you want very fine grained control you can use the trace exit in SupportPac MA0W. With MA0W you can see exactly what API calls are made by the program and those made on its behalf.
[EDIT] Updating the response with some info from the PMR:
The following is from the WMQ V7 Infocenter:
MessageConsumers are single threaded below the Session level, and
any requeuing of poison messages
takes place within the current unit of
work. This does not affect the
operation of the application, however
when poison messages are requeued
under a transacted or
Client_acknowledge Session, the
requeue action itself will not be
committed until the current unit of
work is committed by the application
code or, if appropriate, the
application container code."
Hence, if it is important for the customer to have poison messages
committed immediately after they are
backed out, it is recommended they
either make use of the Application
Server Facilities
(ConnectionConsumer) which can commit
the message immediately, or
another mechanism to move poison
messages from the queue.
Here is the link to this information in the V6 and V7 Information Centers. Since you are using the V6 client so you would want to refer to the V6 Infocenter. Note that with the V6 client, there is no mention in the Infocenter of ASF being able to commit the poison message immediately, even when using a ConnectionConsumer. The way I read it, this means you probably will need to upgrade to the V7 client to get the behavior you are looking for. Will be interested to see if the PMR results in a similar recommendation.
I use MQ for send/receive message between my system and other system. Sometime I found that no response message in response queue, yet other system have already put response message into response queue (check from log). So, how to check which point is cause of problem, how to prove message is not arrive to my response queue.
In addition, when message arrive my queue it will be written to log file.
You can view this in real-time using the QStats interface. The MO71 SupportPac is a desktop client that you can configure to connect similar to WebSphere MQ Explorer. One of the options it has is queue statistics. Each time you view the queue stats, WMQ resets them to zero. So the procedure is this:
Start MO71 and browse the queues.
Filter on the one queue of interest.
View the queue stats a couple of times.
You will see them reset to zero.
Now run your test.
View the queue stats again.
If the remote program actually put a message, you will see that the queue now shows one or more messages PUT.
If your program successfully executed a GET of the message, you will see GET counts equal to the number of PUT counts.
If GET and PUT both zero, the remote program never PUT the response message.
There are a few other approaches to this but this is the easiest. The opposite end of the spectrum is SupportPac MA0W which will show you every API call against that queue, or by PID, or whatever. It shows all the options so if a program tries to open the queue with the wrong options (i.e. open a remote queue for input) it shows that. But MA0W is a installed as an exit and requires the QMgr to be bounced so it's a little invasive.