2017-10-20 24 views
0

イメージを処理し、テーブルレコードと同様にblobを出力するQueueTriggerを持つAzure関数があります。ポイズンキューメッセージの理由を判断する方法

いくつかの大きな画像を処理するときに、私はOutOfMemory例外を実行しました。これにより、キュー項目が毒キューに置かれる可能性があります。

競合状態が存在し、そのパーティションキーと行キーを持つレコードが既に存在するため、テーブルレコードが挿入されるとエラーが発生することがあります。

私は関数内でこれらの問題を回避することができましたが、これを処理するための好ましい方法は、ポイズンメッセージがポイズンキューに置かれた理由または例外を含めることです。そうすれば、私は別のトリガーに毒キューを聞き、何がうまくいかなかったかを評価した上で行動することができます。

これはどのように処理する必要がありますか?私はErrorTriggerを知っていますが、これは例外を取得するのはいいですが、どのように私はそれを引き起こした特定のキュー項目に関連付けることができないのか分かりません。

+0

私はServiceBus Queueでtry/catchとcatchでコードをラップすることでこれを処理しましたが、スタックトレースを取得してメッセージを自分自身で明示的にデッドレターし、メッセージとしてスタックトレースをインクルードします。私はあなたが明示的に毒キューにストレージ・キュー・メッセージを入れることができるかどうかはわかりません。 –

+0

私はそのアプローチを試みましたが、関数が返された後に発生するため、テーブルストレージの例外をキャッチできません。私はそれが記憶の問題のために働くと思います。 – Dexterity

答えて

0

キュートリガーが失敗した後にポイズンストレージキューのメッセージキューを変更する方法はありません。

Azure関数はWebジョブSDKを使用します。 Web Job 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

0

例外とFunctionInvocationフィルタを使用してメッセージを引き起こしたメッセージを追跡するためのハックの方法があります。

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では、関数を上げているかどうかを確認し、例外や辞書からのメッセージを取得することができ、その後、どこか別の場所に保管し

私はわからない(データベースは、など、ログ)例外...

関連する問題