2016-07-05 127 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