2016-07-05 53 views
2

使用NServiceBus 4.3我想在发生某些情况时向错误队列发送消息。首次将消息发送到错误队列

这种情况是,当我收到一条消息时,检查这条消息是否指向我们数据库中的一个或多个项目。如果有多个参考文献,我会投一个AmbiguousItemException并抓住它。我需要通过电子邮件向负责人发送正确的信息。所有这一切都想通了,但我不希望这个消息再次尝试。相反,我宁愿将它移动到错误队列中,以便当我们取回所需的信息时,我们可以添加可空属性并将消息放回队列中进行处理。我试过使用_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); 

回答

6

从你所描述的是什么代码听起来像是你有一个长期运行的业务流程。这是using a Saga的候选人。萨加斯像处理程序一样处理传入的消息,但萨加还允许您跟踪状态。因此,不要尝试将消息踢入错误队列(这不是一个好主意),而是可以在Saga上设置某种类型的标志,例如布尔值或枚举值,这表示您收到的消息是“指的是数据库中的一个或多个项目“,就像你说的那样。

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

一旦你收到必要的信息,你可以采取任何必要的行动,然后发回一条消息给佐贺,告诉它继续其过程和/或标记为完成并关闭它。

You can learn more about Sagas here

+0

所以这可能会工作,但与球队交谈后,我们决定不排队的通知命令,并只让消息错误并移动到错误队列。 –

+1

通知命令可以直接回到佐贺,它可以处理它本身。这也只是一个建议。您可以轻松地在表格中添加记录或向自己发送电子邮件等。混淆错误队列并不是推荐的方法。它不是它设计的。我不会推荐。 –

+2

只需要注意一下,我认为@ColinPear意味着错误队列不应该成为所有业务验证错误的抓手。 –

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); 
} 

A第二头帮手

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"]; 
    } 
} 
+0

这应该起作用,但也许应该指出,在将FLR交给SLR之前,FLR仍然会运行配置的次数。我不知道你是否可以在FLR做这件事的时候插入管道。据我了解,在FLR尝试完成之前,您不会添加标题。 –

+0

@Justin自己正确。您是否有基于异常类型控制FLR的要求?如果可以的话,我可以查看它并在可能的情况下添加一个样本 – Simon