Rabbitmq 有没有一种简单的方法可以订阅EasyNetQ中的默认错误队列?

Rabbitmq 有没有一种简单的方法可以订阅EasyNetQ中的默认错误队列?,rabbitmq,easynetq,Rabbitmq,Easynetq,在我的测试应用程序中,我可以看到处理异常的消息被自动插入到默认的EasyNetQ_default_Error_队列中,这非常好。然后,我可以使用成功地转储或重新获取这些消息,这也可以正常工作,但需要下拉到命令行并对Hosepipe和RabbitMQ API调用,以清除重试消息队列 因此,我认为对于我的应用程序来说,最简单的方法就是订阅错误队列,这样我就可以使用相同的基础设施重新处理它们。但在EastNetQ中,错误队列似乎很特殊。我们需要使用适当的类型和路由ID进行订阅,因此我不确定错误队列的这

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

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

bus.Subscribe(“和这个”,消息)

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

如果我的原始消息的类型是
TestMessage
,那么我希望能够执行以下操作:

bus.Subscribe(“?”,重新处理错误消息)


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

您不能使用简单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);
}
[测试]
[显式(“需要本地主机上的RabbitMQ服务器”)]
public void应该能够订阅错误消息()
{
var errorQueueName=新约定().ErrorQueueNamingConvention();
var queue=queue.declaredable(errorQueueName);
var autoResetEvent=新的autoResetEvent(false);
总线.高级.订阅(队列,(消息,信息)=>
{
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();
返回Task.Factory.StartNew(()=>{});
});
自动resetevent.WaitOne(1000);
}
在此之前,我必须修复在EasyNetQ中编写代码时出现的错误消息中的一个小错误,因此请在尝试之前获得>=0.9.2.73的版本。您可以看到代码示例

代码: (我猜了一下)

“foo”的奇怪之处在于,如果我只是将函数HandleErrorMessage2传递到Consume调用中,它就无法确定返回的是一个void而不是任务,因此无法确定使用哪个重载。(与2012年相比) 分配给var会让它很开心。 您将希望捕获调用的返回值,以便能够通过处理对象来取消订阅

还请注意,有人使用了系统对象名(Queue),而不是将其设置为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)
 {
 }
使用Queue=EasyNetQ.Topology.Queue;
private const string QueueName=“EasyNetQ\u Default\u Error\u Queue”;
公共静态无效应该能够订阅错误消息(IBus总线)
{
动作foo=HandleErrorMessage2;
IQueue queue=新队列(QueueName,false);
总线.高级.消耗(队列,foo);
}
私有静态无效HandleErrorMessage2(IMessage消息、MessageReceivedInfo信息)
{
}

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