Azure 服务总线 - 删除特定消息

问题描述 投票:0回答:2

我正在开发一个系统,该系统将涉及分解为小任务的大量数据同步。我将每个小任务作为作业/消息添加到 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
        }
    }

队列越大,效率会越来越低,但它至少会在删除调用正在进行时停止所有活动并删除指定的消息。

它也只会删除准备处理的消息。将来的消息将被忽略,因此我目前添加了添加“睡眠”消息的功能,以停止处理队列,直到我的消息“准备好”并且我可以删除它们。

微软通知我,他们目前正在开发用于删除特定消息的 API,该 API 将在几个月内推出。在那之前,一切都与解决方法有关。

六月更新:

仍然微软没有关于这个问题的更新,并且上述方法不太理想。我现在修改了我的代码:

我放入消息中的对象有一个新属性:

Guid? MessageId { get; set; }

请注意,Guid 可以为空,只是为了向后兼容

当我想删除一条消息时,我将我的 MessageId 添加到数据库表“DeletedMessage”中。

在处理消息时,我会在 DeletedMessage 表中查找匹配的 Guid,如果找到,我只需 Complete() 消息即可,而不进行正常处理。

这效果很好,但有一点开销。如果您不处理大量消息,那么这不是一个大问题。

另请注意,我最初是通过使用 SequenceNumber 来完成此操作的,但是(奇怪的是)SequenceNumber 在查看消息和检索消息之间会发生变化!这会阻止这个想法发挥作用,除非您如上所述使用自己的 ID。

c# azure azureservicebus
2个回答
0
投票

您可以创建自己的队列清理程序,该程序具有一个消息侦听器,该侦听器可以根据消息的某些条件来查看并放弃或提交消息。如果您预见到实际生产环境也需要清理,这可能是控制器中的一个操作。


0
投票

根据我的实验,不可能从消息队列中删除活动消息。

可以通过拨打

Receive(sequenceNumber)
然后拨打
Complete()
来删除延迟消息。

可以通过拨打

CancelScheduledMessageAsync(sequenceNumber)
删除预定消息。

对于活动消息,您必须确保它们在某个时刻被移至死信队列。

死信队列中的消息可以稍后删除或重新提交。

© www.soinside.com 2019 - 2024. All rights reserved.