2016-10-24 7 views
3

特定のタイプの例外に対してロジックを処理する例外を実装する中心的な場所を用意したいと思います。特定のタイプの例外に対してNsb:スキップSLR +エラーキューを無視する機能

特定の例外の種類が発生した場合、私は内部の構成に応じて、以下のいずれかを実行できるようにしたい:前記第2レベルの再試行せずにすぐにキューを誤差に

  • 送信メッセージ。
  • メッセージを非表示にし、処理キューまたはエラーキューの両方に送信しません。

私たちはTimeSpan.MinValueを返す場合は、メッセージがエラー・キューに入れられるよう、最初のケースではなく、秒1をカバーして、このトピックを見つけた: NServiceBus error handling

それでは、どのように私は2番目のケースを実装するだろうか?両方とも1つのクラスで1つのクラスに実装することをお勧めします。

答えて

3

NServiceBusのバージョン6より前のバージョンでは、IManageMessageFailuresを使用してメッセージの失敗を管理できました。最初のレベルの再試行が試行された後にメッセージを正常に処理できない場合、シリアライゼーション例外のケースを処理することができます。

特定のタイプの例外を無視するか、エラーキューに他のエラーを返して失敗したメッセージを送信するカスタムFaultManagerを実装する方法は次のとおりです。第1レベルのリタイアはまだ発生し、これは第2レベルのリトライではなくキックインすることに注意してください。

public class IssueOrder : ICommand 
{ 
    public bool NotFound { get; set; } 
    public bool HasFaulted { get; set; } 
} 

public class OrderHandler : IHandleMessages<IssueOrder> 
{ 
    public void Handle(IssueOrder message) 
    { 
     if(message.NotFound) 
      throw new OrderNotFoundException(); 

     if(message.HasFaulted) 
      throw new ApplicationException(); 
    } 
} 

public class OrderNotFoundException : Exception 
{ 
} 

public class CustomFaultManager : IManageMessageFailures 
{ 
    private ISendMessages sender; 
    private MessageForwardingInCaseOfFaultConfig config; 
    private BusNotifications notifications; 
    private static ILog Logger = LogManager.GetLogger<CustomFaultManager>(); 

    public CustomFaultManager(ISendMessages sender, IProvideConfiguration<MessageForwardingInCaseOfFaultConfig> config) 
    { 
     this.sender = sender; 
     this.config = config.GetConfiguration(); 
    } 

    public void SerializationFailedForMessage(TransportMessage message, Exception e) 
    { 
    } 

    public void ProcessingAlwaysFailsForMessage(TransportMessage message, Exception e) 
    { 
     if (e is OrderNotFoundException) 
     { 
      //Ignore the exception; 
      Logger.WarnFormat("OrderNotFoundException was thrown. Ignoring the message Id {0}.", message.Id); 
     } 
     else 
     { 
      //Check if you have performed enough retries, ultimately send to error queue 
      SendToErrorQueue(message, e); 
     } 
    } 

    private void SendToErrorQueue(TransportMessage message, Exception ex) 
    { 
     message.TimeToBeReceived = TimeSpan.MaxValue; 
     sender.Send(message, new SendOptions(config.ErrorQueue)); 
     Logger.WarnFormat("Message {0} will was moved to the error queue.", message.Id); 
    } 

    public void Init(Address address) 
    { 
    } 
} 

とカスタムFaultManager登録する:NServiceBusのバージョン6では

var config = new BusConfiguration(); 
//Other configuration code 
config.RegisterComponents(c => 
     { 
      c.ConfigureComponent<CustomFaultManager>(DependencyLifecycle.InstancePerCall); 
     }); 

をしかし、IManageMessageFailuresインタフェースは廃止されました。バージョン12の新しいRecoverability apiでは、より優れたカスタマイズが可能です。例外を無視/ミュートする直接の方法はありません。そのためには、NServiceBU pipelineにカスタム動作が必要であり、既知の手順の1つのステップ(メッセージがエラーキューに移動される前など)でステップを実行します。

+0

もう少し詳しいことを教えてください。私たちはNsb 5を使用していますが、どのようにすべてのケースを実装できるかわかりません。1)メッセージ隠蔽2)通常のSLR 3)IManageMes​​sageFailuresのSLRなし。 「この拡張機能を有効にすると、第2レベルの再試行は呼び出されません」と表示されます。第2に、「メッセージがエラーキューに移動される前に、どのハンドラがイベントに役立つかはわかりません。ただ、SerializationFailedForMessageとProcessingAlwaysFailsForMessage」しかありません。 – YMC

+0

カスタム障害マネージャの実装方法を示すサンプルをまとめています。私と一緒に抱きしめてください。 –

+0

@YMCはコードがあなたのために働くかどうか見てください。また、NSBドキュメントのWebサイトでv5サンプルを更新します。 –

関連する問題