未调用MassTransit故障使用者进行请求/响应 [英] MassTransit fault consumer not invoked for request/response

查看:71
本文介绍了未调用MassTransit故障使用者进行请求/响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在MassTransit 3+中处理请求/响应模式的异常的最佳实践是什么?此处的文档提到如果消息中存在ResponseAddress,,则故障消息将发送到该地址,但是一个使用者如何在该地址接收消息?Bus.Request的ResponseAddress似乎是我无法控制的自动生成的MassTransit地址,因此我不知道如何访问在主要使用者中引发的异常.我想念什么?这是我的代码,用于使用Unity容器注册使用者及其故障使用者:

What is the best practice for handling exceptions in MassTransit 3+ with regard to Request/Response pattern? The docs here mention that if a ResponseAddress exists on a message, the Fault message will be sent to that address, but how does one consumer/receive the messages at that address? The ResponseAddress for Bus.Request seems to be an auto-generated MassTransit address that I don't have control over, so I don't know how to access the exception thrown in the main consumer. What am I missing? Here's my code to register the consumer and its fault consumer using Unity container:

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

这是我对全局消息错误使用者的尝试:

And here's my attempt at a global message fault consumer:

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方法中的做法,但是这样做的缺点是在放弃重试之前会调用每个异常.处理请求/响应异常的正确方法是什么?

This approach DOES work when I use Bus.Publish as opposed to Bus.Request. I also looked into creating an IConsumeObserver and putting my global exception logging code into the ConsumeFault method, but that has the downside of being invoked every exception prior to the re-tries giving up. What is the proper way to handle exceptions for request/response?

推荐答案

首先,MassTransit中的请求/响应支持旨在与 .Request()方法或请求客户端( MessageRequestClient PublishRequestClient ).使用这些方法,如果请求消息的使用者引发异常,则将该异常打包到 Fault< T> 中,然后将其发送到 ResponseAddress .由于 .Request()方法和请求客户端都是异步的,因此使用await将引发异常,并包含来自故障的异常数据.这样就可以设计它,等待请求,请求将完成,超时或发生错误(等待时引发异常).

First of all, the request/response support in MassTransit is meant to be used with the .Request() method, or the request client (MessageRequestClient or PublishRequestClient). With these methods, if the consumer of the request message throws an exception, that exception is packaged into the Fault<T>, which is sent to the ResponseAddress. Since the .Request() method, and the request client are both asynchronous, using await will throw an exception with the exception data from the fault included. That's how it is designed, await the request and it will either complete, timeout, or fault (throw an exception upon await).

如果您试图出于记录目的而放入一些全局异常处理程序"代码,则实际上应该将这些代码记录在服务边界上,而观察者是处理它的最佳方法.这样,您可以只实现 ConsumeFault 方法,并登录到事件接收器.但是,这在使用者管道中是同步的,因此请注意可能引入的延迟.

If you are trying to put in some global "exception handler" code for logging purposes, you really should log those at the service boundary, and an observer is the best way to handle it. This way, you can just implement the ConsumeFault method, and log to your event sink. However, this is synchronous within the consumer pipeline, so recognize the delay that could be introduced.

另一个选择当然是只消耗 Fault< T> ,但是正如您提到的,当请求客户端与标头中的响应地址一起使用时,它不会被发布.在这种情况下,也许您的请求者应该发布一个事件,指示操作X错误,然后您可以在业务上下文级别与服务级别之间记录该事件.

The other option is to of course just consume Fault<T>, but as you mentioned, it does not get published when the request client is used with the response address in the header. In this case, perhaps your requester should publish an event indicating that operation X faulted, and you can log that -- at the business context level versus the service level.

这里有很多选择,只是选择最适合您的用例的一个.

There are many options here, it's just choosing the one that fits your use case best.

这篇关于未调用MassTransit故障使用者进行请求/响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆