【问题标题】:RabbitMQ server thinks that it has delivered messages, RabbitMQ client disagreesRabbitMQ 服务端认为已经投递了消息,RabbitMQ 客户端不同意
【发布时间】:2015-04-16 16:45:49
【问题描述】:

我正在使用 RabbitMQ 将消息传递到工作进程(使用官方 C# 客户端)。在实施过程中,我一直在运行简单的测试,到目前为止一切都很顺利。

我运行了一个测试,我为一个未在侦听(无连接)的工作进程排队消息。一旦我排队了数百条消息,我就开始了这个过程。它创建了它的 IModel,声明了它的队列(已经存在),并开始消费消息(使用 BasicConsume)。这太棒了。这个过程在处理消息时,会为其他队列创建消息。已经有进程在监听这些队列(使用 BasicConsume),因此消息会立即传递给这些客户端(或者服务器认为......)。消息永远不会被处理。

服务器肯定认为消息已经送达(消息都在“未确认”的桶中,而不是“就绪”的桶中),但是 IBasicConsumer.HandleBasicDeliver 从未在客户端被调用。我尝试了几种不同的技术(使用订阅、使用 QueueingBasicConsumer 以及我自己的自定义消费者),结果完全相同。我完全不知所措。如果我关闭连接(这里只有一个连接),那么消息会立即从“未确认”存储桶移动到“就绪”存储桶”。

为什么发送消息时客户端没有收到通知?

查看代码,ModelBase.Close() 调用 ConsumerDispatcher.Shutdown()(ModelBase.cs 第 301 行),然后从那里调用 workService.StopWork()(ConcurrentConsumerDispatcher.cs 第 27 行)。在我看来(通过粗略的代码查看)这会停止连接的 ConsumerWorkService 中的所有工作。相反,ConcurrentConsumerDispatcher.Shutdown() 是否应该在第 27 行调用 workService.StopWork(this)

【问题讨论】:

  • 您好像在某处遗漏了 ack。为什么不使用像 Shuttle 这样的东西来为你处理一切?它会保护你很多问题,github.com/Shuttle
  • 见粗体部分。我没有错过一个确认。为什么不使用穿梭机?因为它不符合我的需求。我不需要 ESB,我需要消息队列系统。

标签: c# rabbitmq amqp


【解决方案1】:

这是 RabbitMQ 客户端中的一个错误,并修复了has already been merged in

它应该在 2015 年 4 月 18 日的下一个夜间版本中可用。

【讨论】:

    【解决方案2】:

    如果你的 BasicConsume 定义了noAck = false,那么在你 Dequeues 后需要运行下一个代码:channel.BasicAck(result.DeliveryTag, false);

    如果您的 BasicConsume 定义了 noAck = true,则在您将消息出列后,它会自动从服务器中删除。

    【讨论】:

    • 所有发送的消息都被确认。
    猜你喜欢
    • 2015-12-19
    • 2013-03-17
    • 2015-09-09
    • 2016-10-12
    • 2018-04-02
    • 1970-01-01
    • 2013-02-14
    • 2012-03-24
    • 2019-12-02
    相关资源
    最近更新 更多