2017-01-06 14 views
0

要求/応答パターンに関してMassTransit 3+の例外を処理するためのベストプラクティスは何ですか? docs hereでは、メッセージにResponseAddressが存在する場合、そのアドレスにFaultメッセージが送信されますが、そのアドレスでメッセージを受信するコンシューマはどのようになりますか? Bus.RequestのResponseAddressは自動生成されたMassTransitのアドレスのように見えますが、私は主なコンシューマにスローされた例外にアクセスする方法を知らないのです。私は何が欠けていますか?ここではユニティ・コンテナを使用して、消費者とその障害、消費者を登録するための私のコードだ:MassTransit障害コンシューマが要求/応答に対して呼び出されない

cfg.ReceiveEndpoint(host, "request_response_queue", e => 
{ 
    e.Consumer<IConsumer<IRequestResponse>>(container); 
    e.Consumer(() => container.Resolve<IMessageFaultConsumer<IRequestResponse>>() as IConsumer<Fault<IRequestResponse>>); 
}); 

そしてここでは、グローバル・メッセージフォルト消費者の私の試みです:私はBus.Publishを使用する場合

public interface IMessageFaultConsumer<TMessage> 
{ 
} 

public class MessageFaultConsumer<TMessage> : IConsumer<Fault<TMessage>>, IMessageFaultConsumer<TMessage> 
{ 
    public Task Consume(ConsumeContext<Fault<TMessage>> context) 
    { 
     Console.WriteLine("MessageFaultConsumer"); 
     return Task.FromResult(0); 
    } 
} 

このアプローチでは、作業を行いますBus.Requestとは対照的です。私はまた、IConsumeObserverを作成し、グローバル例外ログコードをConsumeFaultメソッドに入れてみましたが、再試行の前にすべての例外が呼び出されるという欠点があります。要求/応答の例外を処理する適切な方法は何ですか?

答えて

1

まず、MassTransitでのリクエスト/レスポンスのサポートは、.Request()メソッドまたはリクエストクライアント(MessageRequestClientまたはPublishRequestClient)で使用するためのものです。これらのメソッドでは、リクエストメッセージのコンシューマが例外をスローすると、その例外はFault<T>にパッケージ化され、ResponseAddressに送信されます。 .Request()メソッドと要求クライアントは両方とも非同期であるため、awaitを使用すると、障害の例外データが含まれた例外がスローされます。それがどのように設計されているのか、要求を待っています。完了、タイムアウト、または障害(待機時に例外をスローする)のいずれかが行われます。

ロギングのためにグローバルな「例外ハンドラ」コードを入れようとしている場合は、サービスの境界にそれらを記録する必要があります。オブザーバは、オブザーバを処理する最も良い方法です。この方法では、ConsumeFaultメソッドを実装し、イベントシンクにログするだけです。しかし、これはコンシューマパイプライン内で同期しているため、導入可能な遅延を認識しています。

もう1つのオプションはもちろん、ちょうどFault<T>を消費することですが、前述したように、要求クライアントがヘッダー内の応答アドレスとともに使用されても公開されません。この場合、リクエスタは、操作Xがフォルトしたことを示すイベントを発行し、それをビジネス・コンテキスト・レベル対サービス・レベルで記録する必要があります。

ここでは多くのオプションがありますが、ユースケースに最も適したものを選択するだけです。

関連する問題