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

本文关键字:消息 删除 服务 总线 Azure | 更新日期: 2023-09-27 18:31:18

我正在开发一个系统,该系统将涉及大量数据同步,分解为小任务。我正在将每个小任务作为作业/消息添加到 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 以删除应该在几个月内可用的特定消息。在那之前,一切都与解决方法有关。

六月更新:

Microsoft仍然没有关于此问题的更新,并且上述方法不太理想。我现在已经修改了我的代码,以便:

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

Guid? MessageId { get; set; }

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

当我想删除消息时,我将我的 MessageId 添加到数据库表"已删除消息"中。

在处理消息时,我在 DeletedMessage 表中查找匹配的 Guid,如果找到一个,我只需完成 () 消息而不进行正常处理。

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

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

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

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

根据我的实验,无法从消息队列中删除活动消息。

可以通过调用 Receive(sequenceNumber) 然后调用 Complete() 来删除延迟的消息。

可以通过调用 CancelScheduledMessageAsync(sequenceNumber) 来删除计划的消息。

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

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