简体   繁体   English

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

[英]Azure Storage Queue - processing messages on poison queue

I've been using Azure Storage Queues to post messages too, then write the messages to a db table.我也一直在使用 Azure 存储队列来发布消息,然后将消息写入 db 表。 However I've noticed that when an error occurs processing messages on the queue, the message is written to a poison queue.但是我注意到,当处理队列上的消息时发生错误时,该消息将写入有害队列。

Here is some background to the setup of my app:这是我的应用程序设置的一些背景:

Azure Web App -> Writes message to the queue Azure Web App -> 将消息写入队列

Azure function -> Queue trigger processes the message and writes the contents to a db Azure 函数 -> 队列触发器处理消息并将内容写入数据库

There was an issue with the db schema which caused the INSERTS to fail. db 架构存在问题,导致 INSERTS 失败。 Each message was retried 5 times, which I believe is the default for retrying queue messages, and after the 5th attempt the message was placed on the poison queue.每条消息都重试了 5 次,我相信这是重试队列消息的默认设置,并且在第 5 次尝试后,该消息被放置在有害队列中。

The db schema was subsequently fixed but now I've no way of processing the messages on the poison queue. db 模式随后被修复,但现在我无法处理毒物队列中的消息。

My question is can we recover messages written to the poison queue in order to process them and INSERT them into the db, and if so how?我的问题是我们可以恢复写入毒物队列的消息以便处理它们并将它们插入到数据库中,如果可以,如何恢复?

For your particular problem, I would recommend solution mentioned in question part of this post: Azure: How to move messages from poison queue to back to main queue?对于您的特定问题,我会推荐本文问题部分中提到的解决方案: Azure:如何将消息从有害队列移回主队列?

Please note that name of poison queue == $"{queueName}-poison"请注意毒药队列的名称 == $"{queueName}-poison"

You can use azure management studio(cerulean) and move the message from poison queue to actual queue.您可以使用 azure management studio(cerulean) 并将消息从毒队列移动到实际队列。 Highly recommended tool to access queues and blobs and do any production related activity also.强烈推荐访问队列和 blob 并执行任何与生产相关的活动的工具。 https://www.cerebrata.com/products/cerulean https://www.cerebrata.com/products/cerulean

I am just user of the tool and no way affiliated, i recommended because it is very powerful, very useful and makes you very productive.我只是该工具的用户,没有任何关联,我推荐它是因为它非常强大,非常有用,并且可以让您非常高效。

在此处输入图片说明

Click on move and message can be moved to the actual uploaded queue点击移动,消息可以移动到实际上传的队列中

在此处输入图片说明

In my current project I've created something what is called: "Support functions" in the FunctionApp.在我当前的项目中,我在 FunctionApp 中创建了一个叫做“支持功能”的东西。 It exposes a special HTTP endpoint with Admin authorization level that can be executed at any time.它公开了一个可以随时执行的具有管理员授权级别的特殊 HTTP 端点。

Please See the code below, which solves the problem of reprocessing messages from the poison queue:请看下面的代码,它解决了重新处理来自毒物队列的消息的问题:

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.");
    }
}

Alternatively it may be a good idea to create a new message with the additional metadata (as information that the message has already been processed in the past with no success - then it may be send to the dead letter queue).或者,使用附加元数据创建新消息可能是一个好主意(因为该消息过去已被处理但没有成功 - 然后它可能会被发送到死信队列)。

You have two options你有两个选择

  1. Add another function that is triggered by messages added to the poison queue.添加另一个由添加到毒物队列的消息触发的函数。 You can try adding the contents to the db in this function.您可以尝试在此函数中将内容添加到数据库中。 More details on this approach can be found here .可以在 此处找到有关此方法的更多详细信息。 Of course, if this function too fails to process the message you could check the dequeue count and post a notification that needs manual intervention.当然,如果此函数也无法处理消息,您可以检查出队计数并发布需要手动干预的通知。
  2. Add an int 'dequeueCount' parameter to the function processing the queue and after say 5 retries log the failure instead of letting the message go the poison queue.向处理队列的函数添加一个 int 'dequeueCount' 参数,然后在 5 次重试后记录失败,而不是让消息进入有害队列。 For example you can send an email to notify that manual intervention is required.例如,您可以发送电子邮件通知需要手动干预。

Just point your Azure function to the poison queue and the items in that poison queue will be handled.只需将您的 Azure 函数指向中毒队列,就会处理该中毒队列中的项目。 More details here: https://briancaos.wordpress.com/2018/05/03/azure-functions-how-to-retry-messages-in-the-poison-queue/更多细节在这里: https : //briancaos.wordpress.com/2018/05/03/azure-functions-how-to-retry-messages-in-the-poison-queue/

Azure Storage Explorer(version above 1.15.0) has now added support to move messages from one queue to another. Azure 存储资源管理器(1.15.0 以上的版本)现在添加了将消息从一个队列移动到另一个队列的支持。 This makes it possible to move all, or a selected set of messages, from the poison queue back to the original queue.这使得将所有或选定的一组消息从有害队列移回原始队列成为可能。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM