按值从 Azure 队列服务中删除消息
Deleting a message from Azure Queue Service by value
我正在使用 Azure 存储队列服务来跟踪由多个不同客户端排队的长 运行 作业队列,但我现在需要从队列中删除任何消息(如果有)存在匹配某些给定条件。
我意识到这对于队列来说有点反模式,但该服务确实提供了一些除了简单排队之外的功能(例如 Delete Message
和 Peek Messages
)所以我想我' d 尝试实现它。
我提出的解决方案有效,但不是很优雅而且效率很低 - 我想知道是否可以做得更好 - 或者我是否应该将整个方法合并并使用一种机制通过设计支持此要求(这需要跨不同系统进行大量工作)。这是简化的代码:
var queue = MethodThatGetsTheAppropriateQueueReference();
await queue.FetchAttributesAsync(); //populates the current queue length
if (queue.ApproximateMessageCount.HasValue)
{
// Get all messages and find any messages to be removed.
// this makes those messages unavailable for other clients
// for the visibilityTimeOut period.
// I've set this to the minimum of 1 second - not ideal though
var messages = await queue.GetMessagesAsync(queue.ApproximateMessageCount.Value);
var messagesToDelete = messages.Where(x => x.AsString.Contains(someGuid));
// Delete applicable messages
messagesToDelete.ToList().ForEach(x => queue.DeleteMessageAsync(x));
}
注意最初我尝试使用PeekMessagesAsync()
来避免影响不需要删除的消息,但这不会给你一个PopReceipt
DeleteMessageAsync()
.
要求
题目:
- 有没有办法在不拉下 ALL 消息的情况下执行此操作? (可能有很多)
- 如果 1 不可能,如果我们使用
PeekMessagesAsync()
,是否有办法获取消息的 PopReceipt
?
Is there a way to do this without pulling ALL of the messages down?
(there could be quite a few)
很遗憾没有。您必须 Get
条消息(一次最多 32 条)并分析消息的内容以确定是否应删除该消息。
If 1 isnt possible, is there a way to get the PopReceipt for a message
if we use PeekMessagesAsync()?
同样,不可以。为了获得 PopReceipt
,消息必须出列,这只能通过 GetMessagesAsync()
实现。 PeekMessagesAsync()
只是 returns 消息而不改变其可见性。
可能的解决方案
您可能需要研究 Service Bus Topics and Subscriptions
以了解此类功能。
您可以创建一个 topic
来发送所有消息。
然后您将创建 2 subscriptions
:在一个订阅中,您将设置一个规则来检查消息内容的匹配值,而在另一个订阅中,您将设置一个规则来检查消息内容是否匹配价值。
Azure 服务总线将做的是检查每条到达的消息是否符合规则,并相应地将消息推送到适当的订阅中。这样您就可以很好地分离 should/shouldn 不会被删除的邮件。
我正在使用 Azure 存储队列服务来跟踪由多个不同客户端排队的长 运行 作业队列,但我现在需要从队列中删除任何消息(如果有)存在匹配某些给定条件。
我意识到这对于队列来说有点反模式,但该服务确实提供了一些除了简单排队之外的功能(例如 Delete Message
和 Peek Messages
)所以我想我' d 尝试实现它。
我提出的解决方案有效,但不是很优雅而且效率很低 - 我想知道是否可以做得更好 - 或者我是否应该将整个方法合并并使用一种机制通过设计支持此要求(这需要跨不同系统进行大量工作)。这是简化的代码:
var queue = MethodThatGetsTheAppropriateQueueReference();
await queue.FetchAttributesAsync(); //populates the current queue length
if (queue.ApproximateMessageCount.HasValue)
{
// Get all messages and find any messages to be removed.
// this makes those messages unavailable for other clients
// for the visibilityTimeOut period.
// I've set this to the minimum of 1 second - not ideal though
var messages = await queue.GetMessagesAsync(queue.ApproximateMessageCount.Value);
var messagesToDelete = messages.Where(x => x.AsString.Contains(someGuid));
// Delete applicable messages
messagesToDelete.ToList().ForEach(x => queue.DeleteMessageAsync(x));
}
注意最初我尝试使用PeekMessagesAsync()
来避免影响不需要删除的消息,但这不会给你一个PopReceipt
DeleteMessageAsync()
.
题目:
- 有没有办法在不拉下 ALL 消息的情况下执行此操作? (可能有很多)
- 如果 1 不可能,如果我们使用
PeekMessagesAsync()
,是否有办法获取消息的PopReceipt
?
Is there a way to do this without pulling ALL of the messages down? (there could be quite a few)
很遗憾没有。您必须 Get
条消息(一次最多 32 条)并分析消息的内容以确定是否应删除该消息。
If 1 isnt possible, is there a way to get the PopReceipt for a message if we use PeekMessagesAsync()?
同样,不可以。为了获得 PopReceipt
,消息必须出列,这只能通过 GetMessagesAsync()
实现。 PeekMessagesAsync()
只是 returns 消息而不改变其可见性。
可能的解决方案
您可能需要研究 Service Bus Topics and Subscriptions
以了解此类功能。
您可以创建一个 topic
来发送所有消息。
然后您将创建 2 subscriptions
:在一个订阅中,您将设置一个规则来检查消息内容的匹配值,而在另一个订阅中,您将设置一个规则来检查消息内容是否匹配价值。
Azure 服务总线将做的是检查每条到达的消息是否符合规则,并相应地将消息推送到适当的订阅中。这样您就可以很好地分离 should/shouldn 不会被删除的邮件。