Deadlettering Messages in Queues and Subscriptions
In the previous section it was stated that there are three
scenarios where messages will messages will be deadlettered by the messaging
system.
·
When a message expires and deadlettering for expired messages is
set to true in a queue or subscription.
·
When the max delivery count for a message is exceeded on a queue
or subscription.
·
When a filter evaluation exception occurs in a subscription and
deadlettering is enabled on filter evaluation exceptions.
This section will focus on the second of these three
scenarios and discuss how the use of dead-lettering and delivery counts can be
used to handle service errors and “poison messages” when using Service Bus
queues and topics.
MaxDeliveryCount
Property
Every message in a Service Bus queue or subscription
maintains a count of how many times that message has been received. The
DeliveryCount property of the message starts at zero, and then increments by
one each time a receiving application receives the message.
When a message is received from a queue by an application
using the peek-lock receive mode the receiving application can perform one of
the following operations.
·
Complete – The message is marked as complete and removed from the
queue.
·
Abandon – Message processing is abandoned and is immediately
available on the queue again.
·
Deadletter – The message is moved to the deadletter queue.
·
Differ – The message remains on the queue in the deferred state
and can be received using the message sequence ID.
·
No action – The message will remain on the queue and become
available on the queue again after the time interval specified in the LockDuration
property of the queue.
The two operations that will allow the message to be
received again in the normal way are Abandon and No action. Abandon is
typically called by a receiving application if it cannot process a message and
message processing is to be retried at a later point in time. If a receiving
application terminates without calling one of the above operations on a
message, then no action is taken.
Handling
“Poison Messages”
In message oriented systems a “poison message” is a message
that contains data or information that cannot be processed by the receiving
application.
Suppose the following code is used to receive and process
messages from a queue.
while (true)
{
BrokeredMessage msg =
queueClient.Receive();
if (msg != null)
{
try
{
// Process message
msg.Complete();
}
catch (Exception
ex)
{
// Log error
msg.Abandon();
}
}
}
|
If the message is processed successfully it will be marked
as complete. If an exception occurs during message processing then the
exception will be handled, an error will be logged, and the message will be abandoned
and returned to the queue and will be processed again.
If the message processing exception was related to a service
call, or database operation, and there was a connection failure, the receiving
application will process the message again and may well succeed on the second
try. If, however, the exception was caused by the content of the message, the
application will receive the message again, attempt to process it, catch an
exception and abandon it, receive the message again, attempt to process it, catch
an exception and abandon it, receive the message again, attempt to process it,
catch an exception and abandon it. If there is no mechanism to detect that this
is a “poison message” the cycle will continue indefinitely.