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

时间:2017-10-20 15:26:46

标签: azure azure-functions azure-webjobs

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

有时在处理几个大图像时,我遇到了OutOfMemory异常,这可能导致队列项被放入毒性队列。

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

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

应如何处理?我知道ErrorTrigger,这很容易获得异常,但我不知道如何将它与引起它的特定队列项联系起来。

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

使用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中,您可以检查函数是否引发异常并从字典中获取消息,然后将其存储在其他位置(数据库,日志等)

我不确定这是否会导致表存储异常......