首次将消息发送到错误队列

时间:2016-07-05 12:19:26

标签: c# error-handling nservicebus nservicebus4

使用NServiceBus 4.3我想在出现某些条件时向错误队列发送消息。

场景是当我收到消息时,检查此消息是否指的是我们数据库中的一个或多个项目。如果有多个引用,我会抛出一个AmbiguousItemException并抓住它。我需要通过电子邮件向负责人提供正确的信息。所有这一切都被弄清楚,但我不希望再次尝试这条消息。相反,我宁愿将其移动到错误Queue,所以当我们收到我们需要的信息时,我们可以添加nullable属性并将消息放回队列进行处理。我尝试过使用_bus.ForwardCurrentMessageTo("error")_bus.Send("error", message)_bus.SendLocal(message)。最后一个基本上将消息放在无限循环中。代码有点像这样。

public class MoveToErrorQueue
{
    private readonly IBus _bus;

    public MoveToErrorQueue(IBus bus)
    {
        _bus = bus;
    }

    public virtual void Send(ResubmitMessage message)
    {
        message.Foo= -1;
        _bus.Send("error", message);
    }
}

以及调用它的代码

        try
        {
            //removed for brevity
        }
        catch (AmbiguousItemException ex)
        {
            Log.Error(ex);
            sendNotificationCommand.FailureMessage = ex.Message;
            _moveToErrorQueue.Send(commandMesage);
        }
        SendNotification(sendScanningNotificationCommand);

2 个答案:

答案 0 :(得分:6)

从您所描述的内容来看,您的业务流程似乎很长。这是using a Saga的候选人。 Sagas处理传入的消息,如处理程序,但Saga也允许您跟踪状态。因此,不要试图将消息放入错误队列(这不是一个好主意),而是可以在Saga上设置某种类型的标志,如布尔值或枚举,这将表明您收到的消息是“引用数据库中的一个或多个项目“正如你所说的那样。

设置好标志后,您可以触发某种消息,通知您或者需要将电子邮件发送给您的客户以获取更新信息(这可能是自动化的)。

一旦您收到必要的信息,您可以采取任何必要的行动,然后将信息发送回Saga,告诉它继续其过程和/或将其标记为完整并将其关闭。

You can learn more about Sagas here

答案 1 :(得分:1)

可以插入退休API并返回"无重试"编号基本上将某些异常发送到错误队列

http://docs.particular.net/nservicebus/errors/automatic-retries#second-level-retries-custom-retry-policy-exception-based-policy

var retriesSettings = busConfiguration.SecondLevelRetries();
retriesSettings.CustomRetryPolicy(MyCustomRetryPolicy);

政策

TimeSpan MyCustomRetryPolicy(TransportMessage transportMessage)
{
    if (transportMessage.ExceptionType() == typeof(MyBusinessException).FullName)
    {
        // Do not retry for MyBusinessException
        return TimeSpan.MinValue;
    }

    if (transportMessage.NumberOfRetries() >= 3)
    {
        return TimeSpan.MinValue;
    }

    return TimeSpan.FromSeconds(5);
}

还有一个标题助手

static class ErrorsHeadersHelper
{
    internal static int NumberOfRetries(this TransportMessage transportMessage)
    {
        string value;
        if (transportMessage.Headers.TryGetValue(Headers.Retries, out value))
        {
            return int.Parse(value);
        }
        return 0;
    }

    internal static string ExceptionType(this TransportMessage transportMessage)
    {
        return transportMessage.Headers["NServiceBus.ExceptionInfo.ExceptionType"];
    }
}