Azure 服务总线 - 删除特定消息
Posted
技术标签:
【中文标题】Azure 服务总线 - 删除特定消息【英文标题】:Azure Service Bus - Delete Specific Message 【发布时间】:2015-01-18 14:38:13 【问题描述】:我正在开发一个系统,该系统将涉及大量数据同步,分解为小任务。我将每个小任务作为作业/消息添加到 Azure 服务总线队列中。
我有 X 个工作角色,然后检查队列并处理数据。
我不希望队列中有很多消息,因为目的是处理消息,完成它,然后再次重新添加相同的消息,但安排了 X 分钟的时间。这会给我一个循环来继续处理这些任务。
Azure 功能的优点在于它们为您处理所有服务器端的东西,但缺点是有时很难调试或操作数据。
我想要做的是在 Web 界面中显示队列中的消息列表(我已经使用 PeekBatch 完成了)。然后我希望能够选择部分/全部消息并删除它们。
如果代码中存在错误并且我想停止某种类型的消息以停止,我可能想要这样做。
接下来,我将拥有从网页重新添加消息的功能。也许我可能想提升我的工作人员角色和消息以更快地执行任务(或减慢它们的速度),或者重新添加我已删除的消息。
那么,问题是,我如何才能真正从队列中选择特定消息,然后将其删除?据我所知,没有明显的方法可以做到这一点,如果可能的话,它需要某种解决方法。这听起来有点奇怪。
编辑:
我有一些可行的方法,但这似乎不是一个很好的解决方案:
public void DeleteMessages(List<long> messageIds)
foreach (var msg in Client.ReceiveBatch(100))
if (messageIds.Contains(msg.SequenceNumber))
msg.Complete(); // Deletes the message
else
msg.Abandon(); // Puts it back in the queue
队列越大,效率会越来越低,但它至少会在删除调用正在进行时停止所有活动并删除指定的消息。
它也只会删除准备好处理的消息。将来的消息将被忽略,因此我目前添加了添加“睡眠”消息的功能,以停止处理队列,直到我的消息“准备好”并且我可以删除它们。
Microsoft 通知我,他们目前正在开发 API,以删除应在几个月后可用的特定消息。在那之前,一切都与变通方法有关。
6 月更新:
仍然微软没有在这个问题上更新,上述方法不太理想。我现在修改了我的代码,以便:
我放入消息的对象有一个新属性:
Guid? MessageId get; set;
请注意,Guid 可以为空,只是为了向后兼容
当我想删除一条消息时,我将我的 MessageId 添加到数据库表“DeletedMessage”中。
在处理消息时,我会在 DeletedMessage 表中查找匹配的 Guid,如果找到匹配的 Guid,我只需 Complete() 消息而不进行正常处理。
这很好用,但开销很小。如果您不处理大量消息,那不是什么大问题。
还请注意,我最初是通过使用 SequenceNumber 来执行此操作的,但是(奇怪的是)SequenceNumber 在查看和检索消息之间发生了变化!除非您如上所述使用自己的 ID,否则这会阻止该想法发挥作用。
【问题讨论】:
【参考方案1】:您可以创建自己的队列清理程序,该程序有一个消息侦听器,该侦听器根据消息的某些标准窥视并放弃或提交消息。如果您预见到在实际生产环境中也需要进行清理,这可能是控制器中的一个操作。
【讨论】:
感谢您的回复,但每当我尝试查看消息然后对其执行某些操作(完成、放弃、延迟)时,它总是会出错,说它在上下文中无法执行任何操作。 【参考方案2】:根据我的实验,无法从消息队列中删除活动消息。
可以通过调用Receive(sequenceNumber)
然后调用Complete()
来删除延迟消息。
可以通过调用CancelScheduledMessageAsync(sequenceNumber)
删除预定消息。
对于活动消息,您必须确保它们在某个时候被移至死信队列。
死信队列中的消息随后可以被删除或重新提交。
【讨论】:
以上是关于Azure 服务总线 - 删除特定消息的主要内容,如果未能解决你的问题,请参考以下文章