【问题标题】:Is there an easy way to subscribe to the default error queue in EasyNetQ?有没有一种简单的方法可以订阅 EasyNetQ 中的默认错误队列?
【发布时间】:2013-02-10 03:08:51
【问题描述】:

在我的测试应用程序中,我可以看到处理过的异常消息被自动插入到默认的 EasyNetQ_Default_Error_Queue 中,这很棒。然后,我可以使用 Hosepipe 成功转储或重新排队这些消息,这也可以正常工作,但需要下拉到命令行并调用 Hosepipe 和 RabbitMQ API 以清除重试消息队列。

所以我认为我的应用程序最简单的方法是简单地订阅错误队列,这样我就可以使用相同的基础架构重新处理它们。但在 EastNetQ 中,错误队列似乎很特殊。我们需要使用正确的类型和路由 ID 进行订阅,所以我不确定错误队列的这些值应该是什么:

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

我可以使用简单的API来订阅错误队列,还是需要深入到advanced API

如果我的原始消息的类型是TestMessage,那么我希望能够做这样的事情:

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

其中ErrorMessage 是EasyNetQ 提供的用于包装所有错误的类。这可能吗?

【问题讨论】:

    标签: rabbitmq easynetq


    【解决方案1】:

    您不能使用简单的 API 来订阅错误队列,因为它不遵循 EasyNetQ 队列类型命名约定 - 也许这是应该修复的问题 ;)

    但高级 API 工作正常。您不会得到原始消息,但很容易获得 JSON 表示,您可以很容易地对自己进行反序列化(使用 Newtonsoft.JSON)。以下是您的订阅代码的示例:

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

    在此之前,我必须修复 EasyNetQ 中编写代码的错误消息中的一个小错误,因此请在尝试之前获取 >= 0.9.2.73 的版本。可以看代码示例here

    【讨论】:

    • 感谢迈克的帮助。您认为为此公开一个友好的包装器是个好主意吗?默认情况下,简单的 API 会写入这个错误队列,所以对我来说,有一种机制来透明地处理这些错误也是有意义的。即使使用上面的代码,我认为我需要在错误消息处理程序 (switch (error.BasicProperties.Type)) 中有某种 switch 语句,这将允许我将原始消息反序列化为正确的类型,这有点难看。如果我可以订阅我感兴趣的特定类型的错误,那就太好了。
    • 顺便说一句,我喜欢 EastNetQ 库。感谢您的辛勤工作和出色的文档。
    • 感谢您的客气话!我已将您的建议添加到问题列表github.com/mikehadlow/EasyNetQ/issues/71,但我并不完全相信。
    • 上面的代码不再编译,源链接不再有效,我在任何地方都找不到任何可以回答问题的东西。这是在去年重写的,所以它遵循命名约定吗?现在怎么样了?
    • @TraderhutGames 是的,从那时起 API 发生了很大变化。不过,您仍然必须使用高级 API 来直接访问队列。
    【解决方案2】:

    有效的代码: (我猜了一下)

    'foo' 的诡异之处在于,如果我只是将该函数 HandleErrorMessage2 传递给 Consume 调用,它无法确定它返回的是 void 而不是任务,因此无法确定要使用哪个重载. (对比 2012 年) 分配给一个 var 让它快乐。 您需要捕获调用的返回值,以便能够通过释放对象来取消订阅。

    另请注意,有人使用系统对象名称(队列)而不是使其成为 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)
     {
     }
    

    【讨论】:

      猜你喜欢
      • 2011-08-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多