In JMS source code, there’s a property called ACK_TYPE which is used to identify message status.
For example, as the sample code shared on this GitHub, when executing the message.acknowledge() API, it will internally pass the value of ACK_TYPE to Service Bus Server. According to the ACK_TYPE, Service Bus will invoke the correlated API accordingly.
From JmsMessageConsumer class, we can know that the ACK_TYPE property will be internally used by JMS SDK when invoking the acknowledge() method. For example:
RELEASED = 3; (just unlock the message in service bus, will then get redelivered)
MODIFIED_FAILED = 4; -> Abandon() which increases delivery count
MODIFIED_FAILED_UNDELIVERABLE = 5; -> Defer()
Section 3: How to mitigate the ‘messages abandon’ issue?
Now, back to our topic today, what can we do when we see a lot of abandoned messages in the backend?
Usually, the abandon API will be called mainly in below two scenarios:
Client disconnects with Server and the abandon API will be called by Service Bus server side in case message lost
Client calls the Abandon API to put the message back in to queue because the client cannot process the message at present.
We could check the metrics in the service bus portal, to confirm whether the server is in a healthy status.
However, in most scenario, the abandon API is invoked due to the performance issue on client side which result in the client can’t process the message in time and even exceeding the max Lock duration. This will also lead to a lock lost issue. To improve the client consumer performance, we could check the following things:
Check whether the client machine that is running the code is experiencing performance issues such as some low threads in the thread pool, high CPU on the Client machine or low memory etc.
Check application receive mode. If there are large volumes of messages, we could suggest using asynchronous receives JMS Listener. Here is the reference.
Check whether your client is using JmsDefaultPrefetchPolicy with the default setting of a prefetch value of 1000.
In JmsConnectionFactory (qpid-jms-client-0.59.0_source\qpid-jms-client-0.59.0_source_from_Procyon\org\apache\qpid\jms)
It means that if the Client is not able to process a 1000-messages within the Service Bus lock duration, it will likely end up losing locks on some of the already prefetched messages. In this case, we can reduce this prefetch size
4. If some particular messages are expected to take more time to process, we could consider increasing the lock duration to a greater value. We need to notice that the maximum Lock duration is 5 mins.