2017-01-06 85 views
0

有關請求/響應模式的MassTransit 3+中處理異常的最佳做法是什麼? docs here提到,如果消息中存在響應地址,則故障消息將被髮送到該地址,但是一個消費者如何接收該地址的消息? 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()方法或請求客戶端(MessageRequestClientPublishRequestClient)一起使用。使用這些方法,如果請求消息的使用者拋出異常,則將該異常打包到發送到ResponseAddressFault<T>。由於.Request()方法和請求客戶端都是異步的,因此使用await將拋出一個異常,並且包含故障中的異常數據。這就是它的設計,等待請求,它會完成,超時或錯誤(在等待時拋出異常)。

如果您爲了記錄目的而試圖放入一些全局「異常處理程序」代碼,那麼您確實應該在服務邊界處記錄這些代碼,而觀察者是處理它的最佳方式。這樣,您可以實施ConsumeFault方法,並登錄到事件接收器。但是,這在消費者渠道中是同步的,因此要認識到可能引入的延遲。

另一種選擇當然是消耗Fault<T>,但正如您所提到的,當請求客戶端與頭中的響應地址一起使用時,它不會被髮布。在這種情況下,或許您的請求者應該發佈一個事件,指出操作X發生故障,並且您可以在業務上下文級別與服務級別上記錄該事件。

這裏有很多選擇,它只是選擇一個最適合您的用例。