Nsb 对于某些类型的异常:跳过 SLR + 忽略错误队列的能力

Nsb for certain type of exceptions: skip SLR + ability to ignore error queue

我希望有一个中心位置来为特定类型的异常实施异常处理逻辑。

如果出现特定的异常类型,我希望能够 运行 根据内部配置执行以下操作之一:

我发现这个主题涵盖了第一种情况,但不包括第二种情况,因为如果我们 return TimeSpan.MinValue,消息将被放入错误队列: NServiceBus error handling

那么我该如何实现第二种情况呢?最好都在一个地方实施,一个 class

在 NServiceBus 版本 6 之前,您可以使用 IManageMessageFailures 来管理消息失败。您可以处理序列化异常的情况,或者 - 与您手头的问题更相关 - 在尝试一级重试后无法正常处理消息时。

以下是实现自定义 FaultManager 的方法,该自定义 FaultManager 会忽略特定类型的异常或将失败的消息和其他错误发送回错误队列。请注意,一级退休仍然会发生,并且会启动而不是二级重试。

public class IssueOrder : ICommand
{
    public bool NotFound { get; set; }
    public bool HasFaulted { get; set; }
}

public class OrderHandler : IHandleMessages<IssueOrder>
{
    public void Handle(IssueOrder message)
    {
        if(message.NotFound)
            throw new OrderNotFoundException();

        if(message.HasFaulted)
            throw new ApplicationException();
    }
}

public class OrderNotFoundException : Exception
{
}

public class CustomFaultManager : IManageMessageFailures
{
    private ISendMessages sender;
    private MessageForwardingInCaseOfFaultConfig config;
    private BusNotifications notifications;
    private static ILog Logger = LogManager.GetLogger<CustomFaultManager>();

    public CustomFaultManager(ISendMessages sender, IProvideConfiguration<MessageForwardingInCaseOfFaultConfig> config)
    {
        this.sender = sender;
        this.config = config.GetConfiguration();
    }

    public void SerializationFailedForMessage(TransportMessage message, Exception e)
    {
    }

    public void ProcessingAlwaysFailsForMessage(TransportMessage message, Exception e)
    {
        if (e is OrderNotFoundException)
        {
            //Ignore the exception;
            Logger.WarnFormat("OrderNotFoundException was thrown. Ignoring the message Id {0}.", message.Id);
        }
        else
        {
            //Check if you have performed enough retries, ultimately send to error queue
            SendToErrorQueue(message, e);
        }
    }

    private void SendToErrorQueue(TransportMessage message, Exception ex)
    {
        message.TimeToBeReceived = TimeSpan.MaxValue;
        sender.Send(message, new SendOptions(config.ErrorQueue));
        Logger.WarnFormat("Message {0} will was moved to the error queue.", message.Id);
    }

    public void Init(Address address)
    {
    }
}

并注册自定义 FaultManager:

var config = new BusConfiguration();
//Other configuration code
config.RegisterComponents(c =>
        {
            c.ConfigureComponent<CustomFaultManager>(DependencyLifecycle.InstancePerCall);
        });

然而,在 NServiceBus 的版本 6 中,IManageMessageFailures 接口已被弃用。新的 Recoverability api in version 6 allows for better customization, althrough there's no direct way of ignoring/muting an exception. For that purpose you need a custom behavior in the NServiceBUs pipeline 和 运行 它位于已知步骤之一之间的步骤中(例如,在将消息移至错误队列之前)。