首页 文章

RabbitMq Acks / Republishing

提问于
浏览
0

处理使用Rabbit的C#项目 . 我发现在我看来,在文档中有关于何时因连接或通道死亡而重新传递消息时出现的相互矛盾的信息(哪一个是什么?)

这里的文档:http://www.rabbitmq.com/semantics.html

声明在 Channels 关闭时它会重新发送

可以使用具有重新排队参数(basic.recover,basic.reject和basic.nack)的AMQP方法将消息返回到队列,或者由于在保留未确认消息时关闭通道 . 任何这些情况都会导致消息在早于2.7.0的RabbitMQ版本的队列后面重新排队 . 从RabbitMQ版本2.7.0开始,消息始终以发布顺序保存在队列中,即使存在重新排队或通道关闭 .

但在这里:http://www.rabbitmq.com/tutorials/tutorial-two-dotnet.html

状态:仅在 Worker 连接死亡时

如果消费者在没有发送确认的情况下死亡,RabbitMQ将理解消息未被完全处理并将其重新发送给另一个消费者 . 这样你就可以确保没有消息丢失,即使 Worker 偶尔会死亡 . 没有任何消息超时;只有当工作者连接死亡时,RabbitMQ才会重新传递消息 . 即使处理消息需要非常长的时间,也没关系 .

那么什么时候重新发生呢?当 Worker 或渠道死亡?我可以在一个 Channels 上 Consume 但在另一个 Channels 上 ACK 吗?

目前我创建了一个ChannelManager类,它打开N个通道并在需要时将它们存储在ConcurrentQueue和Queues / Dequeues Channels中,并且还确保我们永远不会低于“最小”可用通道数 . 使用这种方法,我无法确保Consume和Ack在同一个 Channels 上发生......

2 回答

  • 0

    第二个引用的措辞不正确,但该工作页面周围的上下文仍然正确...您以粗体显示的句子将正确更改为:

    当消费者死亡时,RabbitMQ将重新发送消息 .

    这样说不会排除其他合法案件,但会说明他们在本文中提出的要点 .

    ...

    如果要将消息重新排队并重新传递,则必须确保 noAck 设置为false(这是默认设置) . 一旦你有了,你引用的第一段是正确的 .

    ...

    关于你 ChannelManager - 没必要 . 渠道是便宜的,快速的东西,可以根据需要站起来拆除 . 只要您使用所有开放 Channels ,只有1个开放 Channels 或拥有1,000个开放 Channels 是可以的 .

    另一方面,连接是昂贵的 . 为每个应用实例打开一个连接 . 然后在该连接中使用尽可能多的 Channels .

  • 4

    首先,a "channel pool"表示与代理的单独连接,而是与代理通过连接进行的明确讨论 - read more here .

    其次,教程不是真正的文档 . 它有助于理解代理如何工作,但我通常希望作为教程的一部分编写的内容特定于该教程中描述的场景 . 在这种情况下,文档说明了消息可能被重新排队的情况 .

    第三,重新排列和重新发送是不同的事情 . 重新兑换只能在重新排队后进行,但不能保证 . 例如,消息可能会在重新排队之后但在重新传递之前到期(可能是因为没有消费者可以接收消息,或者它在队列中等待的时间太长) .

    最后,传递给消费者的每条消息都会发送一个传递标签 . 该标记特定于 Channels 上的 Channels 和消费者 . 因此,不可能从另一个 Channels ack ,因为另一个 Channels 缺乏传递标签的上下文感知 .

相关问题