未针对请求/响应调用MassTransit故障使用者

时间:2017-01-06 05:46:10

标签: masstransit

在请求/响应模式方面,处理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方法中,但这有一个缺点就是在重新放弃之前调用每个异常。处理请求/响应异常的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

首先,MassTransit中的请求/响应支持旨在与.Request()方法或请求客户端(MessageRequestClientPublishRequestClient)一起使用。使用这些方法,如果请求消息的使用者抛出异常,则该异常将打包到Fault<T>中,并发送到ResponseAddress。由于.Request()方法和请求客户端都是异步的,因此使用await将引发包含故障的异常数据的异常。它是如何设计的,等待请求,它将完成,超时或故障(等待时抛出异常)。

如果你试图加入一些全局&#34;异常处理程序&#34;用于记录的代码,你真的应该在服务边界记录它们,并且观察者是处理它的最佳方式。这样,您就可以实现ConsumeFault方法,并登录到事件接收器。但是,这在消费者管道中是同步的,因此要认识到可能引入的延迟。

另一种选择当然只是消耗Fault<T>,但正如您所提到的,当请求客户端与标头中的响应地址一起使用时,它不会被发布。在这种情况下,您的请求者可能应该发布一个事件,指示操作X出现故障,并且您可以记录该事件 - 在业务环境级别与服务级别。

这里有很多选择,它只是选择最适合您用例的选项。