我一直在玩用于 AMQP 的 RabbitMQ 客户端,我注意到了这一点,ack
并且reject
两者都只需要一个交付标签。如果您使用相同的交货标签ack
会发生什么?reject
RabbitMQ 不会出错,但我想知道这是否应该引发错误,说明交付标签已被“认领”。
AMQP 规范对此有什么要说的吗?
简短的回答
basic.ack
, basic.nack
,basic.reject
和其他一些方法是幂等的,因此使用相同的参数多次调用它们只会生效一次。
长答案
RabbitMQ 上有关于 AMQP 协议的AMQP 规范basic.ack
,您可能已经看到了,但我会根据文档强调
确认一条或多条消息...确认可以针对单个消息或一组消息,直到并包括特定消息
此方法确认通过 Deliver 或 GetOk 方法传递的一条或多条消息。客户端可以要求确认单个消息或一组消息,直至并包括特定消息。
因此,如果您basic.ack
使用不存在的传递标签发送任何内容,则不会发生任何事情,而队列中没有标记为待处理的 ack'ing/nack'ing 的消息,则什么都不会被确认。
basic.reject以类似的方式工作,但仅适用于特定消息。
关于 AMQP 协议的重要时刻是它具有异步设计,因此几乎所有事情都受到竞争条件的影响。RabbitMQ 在设计为高性能和可靠的系统时不会对所有事情都大喊大叫,而不是响亮和沉重。
我可以向您推荐这个用例:例如,您在主线程中使用消息并将其传递给一个或多个子线程,因此可能会发生一个子线程完成处理而另一个子线程稍晚完成的情况。当然,这是一个设计糟糕的架构的例子,但是 RabbitMQ 通常不会关心设计糟糕的生产者和消费者,并且仍然可以工作。