簡體   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