我正在开发一个系统,该系统将涉及分解为小任务的大量数据同步。我将每个小任务作为作业/消息添加到 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
}
}
队列越大,效率会越来越低,但它至少会在删除调用正在进行时停止所有事件并删除指定的消息。
它也只会删除准备处理的消息。将来的消息将被忽略,因此我目前添加了添加“ sleep ”消息的功能,以停止处理队列,直到我的消息“准备好”并且我可以删除它们。
Microsoft 通知我,他们目前正在开发用于删除特定消息的 API,该 API 将在几个月内推出。在那之前,一切都与解决方法有关。
六月更新:
仍然微软没有就此问题进行更新,上述方法不太理想。我现在修改了我的代码,以便:
我放入消息中的对象有一个新属性:
Guid? MessageId { get; set; }
请注意,Guid 可以为空,只是为了向后兼容
当我想删除一条消息时,我将我的 MessageId 添加到数据库表“DeletedMessage”中。
在处理消息时,我会在 DeletedMessage 表中查找匹配的 Guid,如果找到,我只需 Complete() 消息即可,而不进行正常处理。
这效果很好,但有一点开销。如果您不处理大量消息,那么这不是一个大问题。
另请注意,我最初是通过使用 SequenceNumber 来完成此操作的,但是(奇怪的是)SequenceNumber 在查看消息和检索消息之间会发生变化!这会阻止该想法发挥作用,除非您按照上面的方式使用自己的 ID。
最佳答案
您可以创建自己的队列清理程序,该程序具有一个消息监听器,该监听器可以根据消息的某些条件来查看并放弃或提交消息。如果您预见到实际生产环境也需要清理,那么它可能是 Controller 中的一个操作。
关于c# - Azure 服务总线 - 删除特定消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27044605/