繁体   English   中英

如何确定中毒队列消息的原因

[英]How to determine reason for poison queue message

我有一个带有 QueueTrigger 的 azure 函数,它处理图像并输出一个 blob 以及一个表记录。

有时在处理多个大图像时,我会遇到 OutOfMemory 异常,这会导致队列项被放入有害队列。

有时会出现竞争条件,并且插入的表记录会出错,因为已经存在具有该分区键和行键的记录。

我可以在函数中自己解决这些问题,但我首选的处理方式是让有害消息包含导致项目被放入有害队列的原因或异常。 这样我就可以让另一个触发器监听中毒队列,并在评估出了什么问题后采取相应的行动。

这应该如何处理? 我知道 ErrorTrigger,它很高兴获得异常,但我不知道如何将它与导致它的特定队列项目相关联。

队列触发器失败后,无法更改毒物存储队列消息队列。

Azure 函数使用 Web 作业 SDK。 直接使用 Web 作业 SDK 可以覆盖 QueueProcessor.CopyMessageToPoisonQueueAsync。 一些有用的链接:

https://github.com/Azure/azure-webjobs-sdk/issues/1204

https://github.com/Azure/azure-webjobs-sdk-samples/blob/master/BasicSamples/MiscOperations/CustomQueueProcessorFactory.cs

https://github.com/Azure/azure-webjobs-sdk/blob/ffae7c86ea87fd73748186bac2c38c5401b80f68/test/Microsoft.Azure.WebJobs.Host.EndToEndTests/AzureStorageEndToEndTests.cs

有一种使用 FunctionInvocation 过滤器跟踪异常和导致消息的消息的hacky 方法。

public static class QueueFunction
{
    [FunctionName("QueueFunction")]
    [TrackFailedMessages]
    public static void Run([QueueTrigger("myqueue")]string message)
    {
        throw new Exception("OMG");
    }
}

public class TrackFailedMessages : FunctionInvocationFilterAttribute
{
    private static readonly ConcurrentDictionary<Guid, object> QueueParamters = new ConcurrentDictionary<Guid, object>();
    public override Task OnExecutingAsync(FunctionExecutingContext executingContext, CancellationToken cancellationToken)
    {
        if (executingContext.Arguments.TryGetValue("message", out var data))
        {
            QueueParamters.AddOrUpdate(executingContext.FunctionInstanceId, data, (id, obj) => data);
        }
        return Task.CompletedTask;
    }

    public override Task OnExecutedAsync(FunctionExecutedContext executedContext, CancellationToken cancellationToken)
    {
        if (executedContext.FunctionResult.Exception != null &&
            QueueParamters.TryGetValue(executedContext.FunctionInstanceId, out var message))
        {
            executedContext.Logger.LogCritical(
                "The message {message} caused the exception {exception}",
                message,
                executedContext.FunctionResult.Exception.ToString());
        }
        QueueParamters.TryRemove(executedContext.FunctionInstanceId, out var _);
        return Task.CompletedTask;
    }
}

OnExecutinAsync 将在调用函数时被调用。 使用 executionContext 您可以访问函数的参数。 您可以搜索 QueueTrigger 参数并将值存储在字典中,其中 FunctionInstanceId 是键。 FunctionInstanceId 是每次调用的唯一 ID。

在 OnExecuted 中,您可以检查函数是否引发异常并从字典中获取消息,然后将其存储在其他地方(数据库、日志等)

我不确定这是否捕获了表存储异常...

暂无
暂无

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

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