RabbitMq 确认/重新发布
RabbitMq Acks / Republishing
正在处理一个使用 Rabbit 的 C# 项目。我在文档中发现了在我看来是关于何时由于连接或通道失效(哪个是它?)重新传递消息的相互矛盾的信息
这里的文档:
http://www.rabbitmq.com/semantics.html
声明它在频道关闭时重新排队等待传送
Messages can be returned to the queue using AMQP methods that feature
a requeue parameter (basic.recover, basic.reject and basic.nack), or
due to a channel closing while holding unacknowledged messages. Any of
these scenarios caused messages to be requeued at the back of the
queue for RabbitMQ releases earlier than 2.7.0. From RabbitMQ release
2.7.0, messages are always held in the queue in publication order, even in the presence of requeueing or channel closure.
但是这里:http://www.rabbitmq.com/tutorials/tutorial-two-dotnet.html
状态:仅当工作连接终止时
If a consumer dies without sending an ack, RabbitMQ will understand
that a message wasn't processed fully and will redeliver it to another
consumer. That way you can be sure that no message is lost, even if
the workers occasionally die.
There aren't any message timeouts; RabbitMQ will redeliver the message
only when the worker connection dies. It's fine even if processing a
message takes a very, very long time.
那么重新投递实际发生在什么时候?工人或通道何时死亡?我可以在一个频道上 Consume 但在另一个频道上 ACK 吗?
目前我创建了一个 ChannelManager class 打开 N 个通道并根据需要将它们存储在 ConcurrentQueue 和 Queues / Dequeues Channels 中,并且还确保我们永远不会低于 'minimum' 可用通道数数。使用这种方法,我无法确保 Consume 和 Ack 发生在同一频道上...
第二个引用的措辞不正确,尽管该工作页面周围的上下文仍然正确...您以粗体显示的句子将正确更改为:
RabbitMQ will redeliver the message when the consumer dies.
这样说不会排除其他合法案例,但会说明他们在本文中的观点。
...
如果您希望邮件重新排队并重新投递,您必须确保 noAck
设置为 false(这是默认设置)。一旦你有了它,你引用的第一段就是正确的。
...
关于您的 ChannelManager
- 不必要。渠道是便宜、快捷的东西,可以根据需要竖立和拆除。只要您使用所有开放通道,只有 1 个开放通道或 1,000 个开放通道都可以。
另一方面,连接很昂贵。为每个应用程序实例打开一个连接。然后在该连接内根据需要使用任意数量的频道。
首先,我称之为 "channel pool" 会给您的应用程序带来有害的复杂性。通道绝对不能在线程之间共享。将通道视为端点标识符 - 它不代表与代理的单独连接,而是与代理通过连接进行的独特讨论 - read more here.
其次,教程并不是真正的文档。它有助于理解代理的工作原理,但我通常希望作为教程的一部分编写的内容特定于该教程中描述的场景。在这种情况下,文档解释了消息可能重新排队的情况。
第三,重新排队和重新投递是不同的事情。重新投递只能在重新排队后发生,但不能保证。例如,一条消息可能在重新排队后过期,但在重新传递之前过期(可能是因为没有消费者可以接收该消息,或者它在队列中等待的时间太长)。
最后,每条传递给消费者的消息都会发出一个传递标签。该标签特定于频道和频道上的消费者。因此,不可能从另一个渠道 ack
,因为另一个渠道缺乏交付标签的上下文感知。
正在处理一个使用 Rabbit 的 C# 项目。我在文档中发现了在我看来是关于何时由于连接或通道失效(哪个是它?)重新传递消息的相互矛盾的信息
这里的文档: http://www.rabbitmq.com/semantics.html
声明它在频道关闭时重新排队等待传送
Messages can be returned to the queue using AMQP methods that feature a requeue parameter (basic.recover, basic.reject and basic.nack), or due to a channel closing while holding unacknowledged messages. Any of these scenarios caused messages to be requeued at the back of the queue for RabbitMQ releases earlier than 2.7.0. From RabbitMQ release 2.7.0, messages are always held in the queue in publication order, even in the presence of requeueing or channel closure.
但是这里:http://www.rabbitmq.com/tutorials/tutorial-two-dotnet.html
状态:仅当工作连接终止时
If a consumer dies without sending an ack, RabbitMQ will understand that a message wasn't processed fully and will redeliver it to another consumer. That way you can be sure that no message is lost, even if the workers occasionally die.
There aren't any message timeouts; RabbitMQ will redeliver the message only when the worker connection dies. It's fine even if processing a message takes a very, very long time.
那么重新投递实际发生在什么时候?工人或通道何时死亡?我可以在一个频道上 Consume 但在另一个频道上 ACK 吗?
目前我创建了一个 ChannelManager class 打开 N 个通道并根据需要将它们存储在 ConcurrentQueue 和 Queues / Dequeues Channels 中,并且还确保我们永远不会低于 'minimum' 可用通道数数。使用这种方法,我无法确保 Consume 和 Ack 发生在同一频道上...
第二个引用的措辞不正确,尽管该工作页面周围的上下文仍然正确...您以粗体显示的句子将正确更改为:
RabbitMQ will redeliver the message when the consumer dies.
这样说不会排除其他合法案例,但会说明他们在本文中的观点。
...
如果您希望邮件重新排队并重新投递,您必须确保 noAck
设置为 false(这是默认设置)。一旦你有了它,你引用的第一段就是正确的。
...
关于您的 ChannelManager
- 不必要。渠道是便宜、快捷的东西,可以根据需要竖立和拆除。只要您使用所有开放通道,只有 1 个开放通道或 1,000 个开放通道都可以。
另一方面,连接很昂贵。为每个应用程序实例打开一个连接。然后在该连接内根据需要使用任意数量的频道。
首先,我称之为 "channel pool" 会给您的应用程序带来有害的复杂性。通道绝对不能在线程之间共享。将通道视为端点标识符 - 它不代表与代理的单独连接,而是与代理通过连接进行的独特讨论 - read more here.
其次,教程并不是真正的文档。它有助于理解代理的工作原理,但我通常希望作为教程的一部分编写的内容特定于该教程中描述的场景。在这种情况下,文档解释了消息可能重新排队的情况。
第三,重新排队和重新投递是不同的事情。重新投递只能在重新排队后发生,但不能保证。例如,一条消息可能在重新排队后过期,但在重新传递之前过期(可能是因为没有消费者可以接收该消息,或者它在队列中等待的时间太长)。
最后,每条传递给消费者的消息都会发出一个传递标签。该标签特定于频道和频道上的消费者。因此,不可能从另一个渠道 ack
,因为另一个渠道缺乏交付标签的上下文感知。