【发布时间】:2013-12-05 09:35:58
【问题描述】:
我正在编写用于监视和修复 Azure 上 topic subscription 的 dead letter queue 中的消息的功能。
我可以使用_subscriptionClient.PeekBatch(10) 获取消息列表进行显示;但是,当我们想要真正删除其中一条消息时,我们就卡住了。
工作流程是:
- 获取所有消息的列表
- 将特定消息(例如集合中的第 5 条消息)发送回原始队列以进行重新处理
- 将关联的死信消息标记为
.Complete()。
问题在于,虽然我们有消息列表,但如果不先使用 .subscriptionClient.Receive(),我们就无法在特定消息上调用 .Complete()。
由于您不能通过 MessageId .Receive() 发送消息,这是否意味着我们必须像下面一样逐个遍历消息?
public BrokeredMessage GetMessageById(string messageIdentifier)
{
BrokeredMessage matchingMessage = null;
var messageNotFound = true;
var messagesToAbandon = new List<BrokeredMessage>();
while (messageNotFound)
{
var message = _subscriptionClient.Receive();
if (message == null)
{
throw new Exception("Could not find the message on the queue");
}
if (message.MessageId == messageIdentifier)
{
messageNotFound = false;
matchingMessage = message;
}
else
{
messagesToAbandon.Add(message);
}
}
// Unlock all messages that do not match the matching one received.
foreach (var message in messagesToAbandon)
{
message.Abandon();
}
return matchingMessage;
}
我对这种方法的问题是:
- 它不可扩展;如果消息是集合中的第 100 条消息怎么办?我们必须遍历 99 个并将每个标记为废弃
- 如果要放弃的项目太多,我们可能会失去对
matchingMessage的锁定 - 这是一个长期运行的过程
如果在循环中不匹配,我已经考虑过将每条消息标记为已放弃的想法;然而,这会产生我们无限循环相同项目的风险(因为.Abandon() 将它们放回队列中)。
有没有人找到解决这个问题的有效方法?也许将.Defer() 与.Receive(sequenceNumber) 一起使用?
【问题讨论】:
标签: c# azure azureservicebus