AMQP:确认和预取

Ser*_*rge 7 python amqp rabbitmq pika

我尝试了解AMQP协议的某些方面.目前我有RabbitMQ的项目并使用python pika库.所以问题是关于确认和消息预取.

  1. 考虑我们只有消费者的队列(确定这个队列被声明为独占).所以我理解正确:无论我是否使用ack标志?无论如何,我不应该同时处理多个消息,并且没有其他消费者可以采取其他一些仍然排队的消息.最好不要打开确认,因为这可能会降低AMQP服务器负载.

  2. 如果没有确认,预取计数并不意味着什么.正确?

  3. 我不确定预取是如何工作的.我对新消息进行了回调,在最后的声明中,我确认或拒绝了该消息.这是唯一的功能,无论预取计数有多大 - 无论如何,在当前消息完成之前,不会处理另一条消息.那么为什么我需要更改prefetch_count值呢?

提前致谢.

pin*_*ain 27

随着autoack标志未设置,如果你的应用程序消息时未能处理所有接收到的信息将会丢失.如果这种情况非常罕见且消息丢失是您的应用程序中的适当选项(例如,但不限于,日志处理),您可以关闭autoack.

是的,没有autoack设置需要更简单的代理逻辑,因此它使用更少的资源.

对于prefetch count(和prefetch size),这些选项告诉代理可能有多大的预先发送到客户端的有效负载到单个消息.通常它用于节省网络操作的时间以等待新消息.当prefetch size使用时,客户端将接收一个或多个总大小等于或小于预设预设大小(和/或计数,更少)的消息.

无论prefetch countprefetch size规则是他们设置的应用.当其中一个设置为零(未设置)时,将不会应用它们.

最重要的是,预取定义了在客户端已解除备份的更多消息之前发送消息的行为.

结合这两个设置产生这样的东西:

预取消息计数限制并提前发送消息:

条件:

  • 队列:N条消息x 1kb
  • 预取:prefetch-size=5kb, prefetch-count=4
  • 自动包装:off

工作流程:

  • 经纪人向prefetch-count=4客户发送4条消息(限制).4条消息将被标记为un-acked并从队列中移出(因此它们不会被传递给其他客户端).
  • 客户端确认1消息.
  • Broker有-1个消息未被解包(删除该消息)并向客户端发送1个消息(+1 un-aked,-1来自队列,而客户端已经有3个消息未被激活).
  • 客户确认其余3条消息+新发送的消息.
  • 经纪人有-4条消息未被激活,再次发送4条消息,+ 4未发送,-4从队列发送.
  • 客户端确认1消息并失败.
  • Broker将-1 un-acked然后将其余的un-acked移回队列,因此-3 un-aked和+3队列,因此他们可能会再次被传递给这个或其他客户端.

预留大邮件:

条件:

  • 队列:1条消息x 5Kb,N条消息x 1kb
  • 预取:prefetch-size=5kb, prefetch-count=2
  • 自动包装:off

工作流程:

  • 代理向prefetch-size=5kb客户端发送1条消息(受限制),并将该消息标记为un-aked.
  • 客户端确认1消息.
  • Broker有-1条消息未被激活,再次发送2条消息(限制prefetch-count=2,注意,只有第一条消息是5kb,其余的是1kb)并且这些消息被标记为un-acked.
  • 客户端确认1消息并失败.
  • 代理将从消息队列中移出已确认的消息,其余的未确认消息将再次移动到它们所属的队列,因此它们可能会再次传递给此客户端或其他客户端.

使用auto-ack:

条件:

  • 队列:N条消息x 1kb
  • 预取:prefetch-size=5kb, prefetch-count=10
  • 自动包装:on

工作流程:

  • 尽管这两个prefetch-sizeprefetch-count的时候忽略no-ack设置为true(也就是所谓的如何在RabbitMQ的和AMQP文档自动ACK功能),信息将被发送成功后,发送给客户一个接一个,并从队列中删除.

注意,AMQP具有异步架构,因此在某些条件下,两个客户端可以同时接收单个消息.也可以将未发送的消息传递给同一客户端(特别是如果您有单个客户端).

另外,查看prefetch-sizeprefetch-count官方文档并使用这些选项进行一些实验.

PS:autoack基本上是no-ackAMQP标志设置为true.