在请求/响应模式方面,处理MassTransit 3+中的异常的最佳做法是什么? docs here提到如果消息上存在ResponseAddress,则故障消息将被发送到该地址,但是一个消费者/如何在该地址接收消息? Bus.Request的ResponseAddress似乎是一个我无法控制的自动生成的MassTransit地址,因此我不知道如何访问主消费者中抛出的异常。我错过了什么?这是我使用Unity容器注册消费者及其故障消费者的代码:
cfg.ReceiveEndpoint(host, "request_response_queue", e =>
{
e.Consumer<IConsumer<IRequestResponse>>(container);
e.Consumer(() => container.Resolve<IMessageFaultConsumer<IRequestResponse>>() as IConsumer<Fault<IRequestResponse>>);
});
这是我对全球消息故障消费者的尝试:
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.Publish而不是Bus.Request时,这种方法可行。我还研究了如何创建一个IConsumeObserver并将我的全局异常日志记录代码放入ConsumeFault方法中,但这有一个缺点就是在重新放弃之前调用每个异常。处理请求/响应异常的正确方法是什么?
答案 0 :(得分:1)
首先,MassTransit中的请求/响应支持旨在与.Request()
方法或请求客户端(MessageRequestClient
或PublishRequestClient
)一起使用。使用这些方法,如果请求消息的使用者抛出异常,则该异常将打包到Fault<T>
中,并发送到ResponseAddress
。由于.Request()
方法和请求客户端都是异步的,因此使用await将引发包含故障的异常数据的异常。它是如何设计的,等待请求,它将完成,超时或故障(等待时抛出异常)。
如果你试图加入一些全局&#34;异常处理程序&#34;用于记录的代码,你真的应该在服务边界记录它们,并且观察者是处理它的最佳方式。这样,您就可以实现ConsumeFault
方法,并登录到事件接收器。但是,这在消费者管道中是同步的,因此要认识到可能引入的延迟。
另一种选择当然只是消耗Fault<T>
,但正如您所提到的,当请求客户端与标头中的响应地址一起使用时,它不会被发布。在这种情况下,您的请求者可能应该发布一个事件,指示操作X出现故障,并且您可以记录该事件 - 在业务环境级别与服务级别。
这里有很多选择,它只是选择最适合您用例的选项。