Azure存储队列 - 处理有毒队列上的消息

时间:2017-10-23 12:45:20

标签: c# azure azure-storage-queues poison-queue

我一直在使用Azure存储队列发布消息,然后将消息写入数据库表。但是我注意到,当处理队列中的消息时发生错误时,消息将被写入毒性队列。

以下是我的应用设置的一些背景信息:

Azure Web App - >将消息写入队列

Azure功能 - >队列触发器处理消息并将内容写入db

db架构存在问题,导致INSERTS失败。每条消息重试5次,我认为这是重试队列消息的默认值,并且在第5次尝试之后,消息被放置在毒性队列中。

随后修复了db模式,但现在我无法处理毒性队列中的消息。

我的问题是我们是否可以恢复写入毒性队列的消息以便处理它们并将它们插入到数据库中,如果是这样的话?

6 个答案:

答案 0 :(得分:2)

对于您的特定问题,我会推荐此帖中提到的问题部分:Azure: How to move messages from poison queue to back to main queue?

请注意毒药队列名称== $"{queueName}-posion"

答案 1 :(得分:1)

您可以使用azure管理工作室(蔚蓝)并将消息从中毒队列移至实际队列。强烈推荐使用该工具来访问队列和Blob,也可以进行任何与生产相关的活动。 https://www.cerebrata.com/products/cerulean

我只是该工具的用户,没有任何关联,我建议这样做,因为它非常强大,非常有用并且使您非常有生产力。

enter image description here

单击“移动”,邮件可以移动到实际上传的队列中

enter image description here

答案 2 :(得分:0)

您有两个选择

  1. 添加由添加到毒物队列的消息触发的另一个函数。您可以尝试在此函数中将内容添加到db。有关此方法的更多详细信息,请参见here。当然,如果此功能也无法处理消息,您可以检查出队计数并发布需要手动干预的通知。
  2. 将int'dequeueCount'参数添加到处理队列的函数中,并在说5次重试后记录失败,而不是让消息进入毒性队列。例如,您可以发送电子邮件通知需要手动干预。

答案 3 :(得分:0)

在我当前的项目中,我已经在FunctionApp中创建了一个称为“支持功能”的东西。它公开了具有 Admin 授权级别的特殊HTTP终结点,该终结点可以随时执行。

请参见下面的代码,该代码解决了从毒物队列重新处理消息的问题:

public static class QueueOperations
{
    [FunctionName("Support_ReprocessPoisonQueueMessages")]
    public static async Task<IActionResult> Support_ReprocessPoisonQueueMessages([HttpTrigger(AuthorizationLevel.Admin, "put", Route = "support/reprocessQueueMessages/{queueName}")]HttpRequest req, ILogger log,
        [Queue("{queueName}")] CloudQueue queue,
        [Queue("{queueName}-poison")] CloudQueue poisonQueue, string queueName)
    {
        log.LogInformation("Support_ReprocessPoisonQueueMessages function processed a request.");

        int.TryParse(req.Query["messageCount"], out var messageCountParameter);
        var messageCount = messageCountParameter == 0 ? 10 : messageCountParameter;

        var processedMessages = 0;
        while (processedMessages < messageCount)
        {
            var message = await poisonQueue.GetMessageAsync();
            if (message == null)
                break;

            var messageId = message.Id;
            var popReceipt = message.PopReceipt;

            await queue.AddMessageAsync(message); // a new Id and PopReceipt is assigned
            await poisonQueue.DeleteMessageAsync(messageId, popReceipt);
            processedMessages++;
        }

        return new OkObjectResult($"Reprocessed {processedMessages} messages from the {poisonQueue.Name} queue.");
    }
}

或者,用附加的元数据创建一条新消息可能是一个好主意(因为该消息过去曾经被处理过,但没有成功,因此可能会被发送到死信队列中。) >

答案 4 :(得分:0)

只需将您的Azure函数指向毒性队列,该毒性队列中的项目将被处理。此处有更多详细信息:https://briancaos.wordpress.com/2018/05/03/azure-functions-how-to-retry-messages-in-the-poison-queue/

答案 5 :(得分:0)

Azure 存储资源管理器(1.15.0 以上的版本)现在添加了将消息从一个队列移动到另一个队列的支持。这使得将所有或选定的一组消息从有害队列移回原始队列成为可能。

https://github.com/microsoft/AzureStorageExplorer/issues/1064