EasyNetQ是否支持nack?

时间:2015-10-16 21:51:56

标签: rabbitmq easynetq

我真正想要做的是在当前消费者拒绝该消息的情况下将消息留在队列中。在RabbitMQ中,我可以发送一个NACK来完成这个任务。 EasyNetQ是否支持NACK?有没有其他方法可以实现我正在寻找的行为?

更新:不是很多回复,所以我想知道人们通常如何处理EasyNetQ中缺少NACK的问题。没有相当于basic.reject限制消费者“我总是可以处理每个消息”的场景。我想消费者可能抛出一个特定的“被拒绝”异常,导致EasyNetQ将消息出列到错误队列,我可以重新排列带有这些错误的消息。还有其他人有其他解决方法吗?

3 个答案:

答案 0 :(得分:2)

我使用EasyNetQ差不多一年了,但无论我们如何调整它(除了其他东西之外还添加了我们自己的IConsumerErrorStrategy实现)我从来没有真正按照我想要的方式工作。在RequestAsync处理程序中执行SubscribeAsync时,它是单线程的事实给了我们一些意想不到的行为(有时是死锁)。

我们的解决方案是从EasyNetQ迁移。在与官方RabbitMq客户端合作一段时间后,我花了几天时间编写超薄客户端。它受EasyNetQ的影响,支持EasyNetQ的大部分概念。但是,我添加了一些简洁的功能,如可插入的消息上下文。我认为我刚刚添加的IAdvancedMessageContext的Nack功能可以适合您:

var client = service.GetService<IBusClient<AdvancedMessageContext>>();
client.RespondAsync<BasicRequest, BasicResponse>((req, ctx) =>
{
  ctx?.Nack(); // the context implements IAdvancedMessageContext.
  return Task.FromResult<BasicResponse>(null);
}, cfg => cfg.WithNoAck(false));

如果您有兴趣,可以在Github page(尤其是NackTests.cs)了解更多相关信息。

答案 1 :(得分:1)

我认为您可以通过实现自己的IConsumerErrorStrategy来改变行为:

https://github.com/EasyNetQ/EasyNetQ/blob/master/Source/EasyNetQ/Consumer/DefaultConsumerErrorStrategy.cs

但是如果您需要这种控制,您可以考虑直接使用RabbitMQ客户端吗?

答案 2 :(得分:1)

听起来你正试图处理失败。您可以NACK消息,但这意味着它位于队列的头部。太棒了,但是这意味着你最终会得到一堆真实无法处理的消息,你将无法真正处理真实的消息。

我在使用RabbitMQ时一直使用的解决方案是利用EasyNetQ的默认错误处理,并有一个单独的应用程序来重新发送消息。也就是说,当在RabbitMQ中捕获异常时,它将消息路由到名为&#34; EasyNetQ_Default_Error_Queue&#34;的队列。您可以覆盖此名称,并将不同的队列转到不同的错误队列,但是现在让我们坚持使用默认值。然后,您可以使用Windows Service / Azure Worker角色阅读这些消息,并确定要执行的操作。这可能包括有一个&#34; RetryCount&#34;在你的邮件信封/包装上,以确保它只循环这么多次。总而言之,这将是一项工作。

您所发现的是许多人在使用RabbitMQ / EasyNetQ时遇到的问题。她很生气。

相关问题