在我的测试应用程序中,我可以看到处理过的异常消息被自动插入到默认的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提供的用于包装所有错误的类。这可能吗?
答案 0 :(得分:3)
您不能使用简单的API订阅错误队列,因为它不遵循EasyNetQ队列类型命名约定 - 也许这是应该修复的东西;)
但Advanced 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中编写代码之前的错误消息中的一个小错误,所以请在尝试之前获得版本&gt; = 0.9.2.73。您可以看到代码示例here
答案 1 :(得分:0)
有效的代码: (我猜了一下)
与foo&#39;的混乱。是因为如果我只是将函数HandleErrorMessage2传递给Consume调用,它就不能确定它返回一个void而不是一个Task,因此无法确定要使用哪个重载。 (VS 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)
{
}