Azure Service Bus 死信队列产生的原因

服务总线中有几个活动会导致从消息引擎本身将消息推送到 DLQ。 如

  • 超过 MaxDeliveryCount
  • 超过 TimeToLive
  • 处理订阅规则时的错误
  • 应用程序主动设置信息进入死信队列

进入死信队列(DLQ)里面的数据 不会自动执行清理操作。 消息将保留在 DLQ 中,直到显式从 DLQ 中检索它们以及对死信消息调用 Complete() 为止。可以使用Service Bus Explorer工具来查看死信队列中消息

 

【服务总线 Azure Service Bus】ServiceBus 队列中死信(DLQ - Dead Letter Queue)问题_Service Bus

也同时可以看见该条消息进入死信队列的根本原因:

【服务总线 Azure Service Bus】ServiceBus 队列中死信(DLQ - Dead Letter Queue)问题_死信队列_02

 

 Moving messages to the DLQ

There are several activities in Service Bus that cause messages to get pushed to the DLQ from within the messaging engine itself. An application can also explicitly move messages to the DLQ.

As the message gets moved by the broker, two properties are added to the message as the broker calls its internal version of the ​​DeadLetter​​​ method on the message: ​​DeadLetterReason​​​ and ​​DeadLetterErrorDescription​​.

Applications can define their own codes for the ​​DeadLetterReason​​ property, but the system sets the following values.

MOVING MESSAGES TO THE DLQ DeadLetterReasonDeadLetterErrorDescriptionHeaderSizeExceededThe size quota for this stream has been exceeded.TTLExpiredExceptionThe message expired and was dead lettered. See the ​​Exceeding TimeToLive​​ section for details.Session ID is null.Session enabled entity doesn't allow a message whose session identifier is null.MaxTransferHopCountExceededThe maximum number of allowed hops when forwarding between queues. Value is set to 4.MaxDeliveryCountExceededExceptionMessageMessage could not be consumed after maximum delivery attempts. See the ​​Exceeding MaxDeliveryCount​​ section for details.

死信问题:

一:队列中存在死信需求如何处理,让这个队列恢复正常?

死信是由于客户端无法正常消费消息产生的,Service Bus会将这些无法正常消费的消息移动到另外的死信队列中,这个是不会影响原有队列的消息的消费和使用。

二:队列中出现死信后是否可以重新发送消息?

死信是已经发送到service bus但消费端无法正常消费的消息,这不影响再次向队列发送消息。

三:消息到死信队列后,怎么操作可以让消息重新到活动队列?

不能使消息重新回到活动队列。因为死信队列的用途是存放无法传递给任何接收方的消息或无法处理的消息。 然后,可从 DLQ 中删除和检查这些消息。 应用程序可能程序员的帮助下,更正问题并重新提交消息,记录出错的实际情况和执行更正操作

  如需要通过程序的方式获取死信队列中的消息,获取消息的方式和正常队列一样,把queueName变为死信队列的路径,通过QueueClient.FormatDeadLetterPath(queueName)方式获取。也可以直接指定为以下格式的路径:

<queue path>/$deadletterqueue
<topic path>/Subscriptions/<subscription path>/$deadletterqueue

参考代码如:

【服务总线 Azure Service Bus】ServiceBus 队列中死信(DLQ - Dead Letter Queue)问题_DLQ_03

根据Azure官方目前的获取Queue中消息的方法,只需替换QueueName

【服务总线 Azure Service Bus】ServiceBus 队列中死信(DLQ - Dead Letter Queue)问题_应用程序_04

 

 

 全部实例代码:​​https://github.com/Azure/azure-service-bus/blob/master/samples/DotNet/Microsoft.ServiceBus.Messaging/DeadletterQueue/Program.cs​

 

参考资料

服务总线死信队列概述:​​https://docs.azure.cn/zh-cn/service-bus-messaging/service-bus-dead-letter-queues​

 

 

当在复杂的环境中面临问题,格物之道需:浊而静之徐清,安以动之徐生。 云中,恰是如此!