2013-02-25 107 views
6

在我的測試應用程序中,我可以看到處理異常的消息被自動插入默認的EasyNetQ_Default_Error_Queue,這非常棒。然後,我可以使用Hosepipe成功轉儲或重新發送這些消息,這也可以正常工作,但需要下降到命令行並針對Hosepipe和RabbitMQ API調用以清除重試消息的隊列。有沒有簡單的方法來訂閱EasyNetQ中的默認錯誤隊列?

所以我想我的應用程序最簡單的方法是隻訂閱錯誤隊列,所以我可以使用相同的基礎結構重新處理它們。但在EastNetQ中,錯誤隊列似乎很特殊。我們需要使用適當的類型和路由ID認購,所以我不知道這些值應該是什麼錯誤隊列:

bus.Subscribe<WhatShouldThisBe>("and-this", ReprocessErrorMessage);

我可以使用簡單的API訂閱錯誤隊列,或者我需要挖掘到advanced API

如果我的原始郵件的類型是TestMessage,然後我想能夠做這樣的事情:

bus.Subscribe<ErrorMessage<TestMessage>>("???", ReprocessErrorMessage);

其中ErrorMessage是EasyNetQ提供包裹所有錯誤的類。這可能嗎?

回答

3

不能使用簡單的API訂閱錯誤隊列,因爲它不遵循EasyNetQ隊列類型命名約定 - 也許在這個時候,應該是固定的;)

但高級API工作正常。你不會得到原始的消息,但很容易獲得JSON表示,你可以很容易地使用它來解序列化(使用Newtonsoft.JSON)。這裏是你的,申購代碼應該是什麼樣子的例子:我不得不修復錯誤消息在EasyNetQ編寫代碼之前,這個工作一個小錯誤,所以請嘗試之前得到一個版本> = 0.9.2.73

[Test] 
[Explicit("Requires a RabbitMQ server on localhost")] 
public void Should_be_able_to_subscribe_to_error_messages() 
{ 
    var errorQueueName = new Conventions().ErrorQueueNamingConvention(); 
    var queue = Queue.DeclareDurable(errorQueueName); 
    var autoResetEvent = new AutoResetEvent(false); 

    bus.Advanced.Subscribe<SystemMessages.Error>(queue, (message, info) => 
    { 
     var error = message.Body; 

     Console.Out.WriteLine("error.DateTime = {0}", error.DateTime); 
     Console.Out.WriteLine("error.Exception = {0}", error.Exception); 
     Console.Out.WriteLine("error.Message = {0}", error.Message); 
     Console.Out.WriteLine("error.RoutingKey = {0}", error.RoutingKey); 

     autoResetEvent.Set(); 
     return Task.Factory.StartNew(() => { }); 
    }); 

    autoResetEvent.WaitOne(1000); 
} 

出來。你可以看到代碼示例工程here

+0

感謝您的幫助邁克。你認爲爲此公開一個友好的包裝會是一個好主意嗎?默認情況下,簡單的API寫入這個錯誤隊列,所以對我來說它有一個機制可以透明地使用這些錯誤。即使使用上面的代碼,我想我需要在錯誤消息處理程序('switch(error.BasicProperties.Type)')中使用某種switch語句,然後我可以將原始消息反序列化爲正確的類型,這有點醜陋。如果我可以訂閱我感興趣的特定類型的錯誤,那將會很好。 – 2013-02-25 11:22:15

+0

順便說一句我喜歡EastNetQ圖書館。感謝您的辛勤工作和出色的文檔。 – 2013-02-25 11:22:48

+0

感謝您的好評!我已將您的建議添加到問題列表https://github.com/mikehadlow/EasyNetQ/issues/71,但我並不完全相信。 – 2013-02-25 15:34:31

0

代碼:

與「富」的screwyness是因爲如果我只是傳遞函數HandleErrorMessage2進入消費調用,它可以」 (我參加了一個猜測)不知道它會返回一個void而不是一個Task,所以不能確定使用哪個超載。 (VS 2012) 分配給一個變種使它感到高興。 您將希望通過配置對象來捕獲調用的返回值以便取消訂閱。

另請注意,有人使用系統對象名稱(隊列)而不是使其成爲EasyNetQueue或某事,因此您必須添加使用澄清編譯器,或完全指定它。

using Queue = EasyNetQ.Topology.Queue; 

    private const string QueueName = "EasyNetQ_Default_Error_Queue"; 
    public static void Should_be_able_to_subscribe_to_error_messages(IBus bus) 
    { 
    Action <IMessage<Error>, MessageReceivedInfo> foo = HandleErrorMessage2; 

    IQueue queue = new Queue(QueueName,false); 
    bus.Advanced.Consume<Error>(queue, foo); 
    } 

    private static void HandleErrorMessage2(IMessage<Error> msg, MessageReceivedInfo info) 
{ 
} 
相關問題