2017-01-06 1 views
0

요청/응답 패턴과 관련하여 MassTransit 3+에서 예외를 처리하는 가장 좋은 방법은 무엇입니까? docs here은 ResponseAddress가 메시지에 존재하면 오류 메시지가 해당 주소로 보내지지만 한 소비자는 해당 주소에서 메시지를 어떻게 받습니까? 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)와 함께 사용하기위한 것입니다. 이러한 메서드를 사용하면 요청 메시지의 소비자가 예외를 throw하는 경우 해당 예외는 Fault<T>에 패키지화되어 ResponseAddress으로 전송됩니다. .Request() 메소드와 요청 클라이언트가 모두 비동기이기 때문에 await을 사용하면 포함 된 오류의 예외 데이터와 함께 예외가 발생합니다. 이것이 설계된 방식으로 요청을 기다리고 완료, 시간 초과 또는 오류 (대기시 예외 발생)가 발생합니다.

로깅을 위해 전역 "예외 처리기"코드를 넣으려면 서비스 경계에있는 코드를 기록해야하며 옵저버가이를 처리하는 가장 좋은 방법입니다. 이렇게하면 ConsumeFault 메서드를 구현하고 이벤트 싱크에 로그온 할 수 있습니다. 그러나 이는 소비자 파이프 라인 내에서 동기식이므로 도입 될 수있는 지연을인지해야합니다.

다른 옵션은 당연히 Fault<T>을 소비하지만, 언급 한대로 요청 클라이언트가 헤더의 응답 주소와 함께 사용될 때 게시되지 않습니다. 이 경우 요청자는 작업 X가 실패했음을 나타내는 이벤트를 게시해야하며 비즈니스 컨텍스트 수준과 서비스 수준에서이를 기록 할 수 있습니다.

여기에는 여러 가지 옵션이 있지만 사용 사례에 가장 적합한 옵션을 선택하는 것만으로 충분합니다.

관련 문제