如何避免消息进入 `deadletter` 队列 azure 服务总线
How to avoid message going to `deadletter` queue azure service bus
我正在使用来自服务总线 topic/subscription 的消息。 ProcessMessage
将消息添加到一个容量有界队列(一次不超过 200 条消息)。完成一条消息处理后,我将其设为 CompleteAsync
,仅当 ProcessMessage
给出 true
.
时
现在,如果发生某些异常,比如队列已满且未准备好接收任何新消息,那么我将生成异常并且 ProcessMessage
给出 false
。在这种情况下 _subscriptionClient.CompleteAsync
未调用,但消息将进入 deadletter
队列。
如何预防?消息不应该进入 deadletter
队列,它应该等待一段时间来处理?
注意 - 我根据评论建议添加了 AbandonAsync
逻辑,但消息仍然进入死信状态并且不会重新出现在主题订阅中。求推荐!
Max delivery count = 5, 已尝试 5 次,然后移至 deadletters
_subscriptionClient = new SubscriptionClient(connectionString, topicName, subscriptionName);
_subscriptionClient.RegisterMessageHandler(
async (message, token) =>
{
if (await ProcessMessage(message, token))
{
await _subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
}
else
{
await _subscriptionClient.AbandonAsync(message.SystemProperties.LockToken);
}
},
new MessageHandlerOptions(ExceptionReceivedHandler) { MaxConcurrentCalls = 1, AutoComplete = false });
private async Task<bool> ProcessMessage(Message message, CancellationToken token)
{
var processed = false;
try
{
//adding message to queue for further process
processed = true;
}
catch
{
//in case queue is full, generating exception and return false
processed = false;
}
return processed;
}
我的理解是,如果 unprocessed/not 完成,您会希望消息变成死信。
无论何时将消息传递给客户端 - 但由于任何原因尚未完成 - 该消息的传递计数将自动增加 1。当传递计数与 MaxDeliveryCount 的计数匹配时 - 消息自动移至死信队列。
话虽如此,如果不增加传递量或在达到特定消息的最大传递计数时禁用消息向死信队列的移动,则无法传递消息。
话虽如此,可能有两种可能的解决方案非常符合您的要求:
- 具有非常大的 MaxDelivery 计数。
- 使用死信队列中的消息 - 将数据重新发送到队列 - 这在您的方案中可能没有用。但只是想将其添加为建议 - 以防万一。
我正在使用来自服务总线 topic/subscription 的消息。 ProcessMessage
将消息添加到一个容量有界队列(一次不超过 200 条消息)。完成一条消息处理后,我将其设为 CompleteAsync
,仅当 ProcessMessage
给出 true
.
现在,如果发生某些异常,比如队列已满且未准备好接收任何新消息,那么我将生成异常并且 ProcessMessage
给出 false
。在这种情况下 _subscriptionClient.CompleteAsync
未调用,但消息将进入 deadletter
队列。
如何预防?消息不应该进入 deadletter
队列,它应该等待一段时间来处理?
注意 - 我根据评论建议添加了 AbandonAsync
逻辑,但消息仍然进入死信状态并且不会重新出现在主题订阅中。求推荐!
Max delivery count = 5, 已尝试 5 次,然后移至 deadletters
_subscriptionClient = new SubscriptionClient(connectionString, topicName, subscriptionName);
_subscriptionClient.RegisterMessageHandler(
async (message, token) =>
{
if (await ProcessMessage(message, token))
{
await _subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
}
else
{
await _subscriptionClient.AbandonAsync(message.SystemProperties.LockToken);
}
},
new MessageHandlerOptions(ExceptionReceivedHandler) { MaxConcurrentCalls = 1, AutoComplete = false });
private async Task<bool> ProcessMessage(Message message, CancellationToken token)
{
var processed = false;
try
{
//adding message to queue for further process
processed = true;
}
catch
{
//in case queue is full, generating exception and return false
processed = false;
}
return processed;
}
我的理解是,如果 unprocessed/not 完成,您会希望消息变成死信。
无论何时将消息传递给客户端 - 但由于任何原因尚未完成 - 该消息的传递计数将自动增加 1。当传递计数与 MaxDeliveryCount 的计数匹配时 - 消息自动移至死信队列。
话虽如此,如果不增加传递量或在达到特定消息的最大传递计数时禁用消息向死信队列的移动,则无法传递消息。
话虽如此,可能有两种可能的解决方案非常符合您的要求:
- 具有非常大的 MaxDelivery 计数。
- 使用死信队列中的消息 - 将数据重新发送到队列 - 这在您的方案中可能没有用。但只是想将其添加为建议 - 以防万一。