RabbitMQ - 升级到新版本并获得了很多"PRECONDITION_FAILED未知交付标签1"

Bic*_*ick 16 rabbitmq

刚刚升级到RabbitMQ的新版本 - 2.3.1 - 现在出现以下错误:

PRECONDITION_FAILED unknown delivery tag 1  
Run Code Online (Sandbox Code Playgroud)

...随后关闭频道.这适用于较旧的RabbitMQ,没有客户端更改.


在应用程序行为方面:

当App A想要向App b发送异步消息并从B接收答案时,这是算法:

  1. 应用A生成唯一ID并将其放入消息对象中
  2. 然后,App A订阅一个新的队列,队列名称和路由键都等于uuid.
  3. 应用B打开消息,进行一些计算并使用收到的路径将结果返回到通道.
  4. 应用A获得答案并关闭队列.

到目前为止,1.7.0一切都很顺利.2.3.1出了什么问题?


当应用程序A调用时basicPublish(),应用程序B立即抛出以下异常:

com.rabbitmq.client.ShutdownSignalException: channel error; reason: {#method<channel.close>(reply-code=406,reply-text=PRECONDITION_FAILED - unknown delivery tag 1,class-id=60,method-id=80),null,""}
    at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:191)
    at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:159)
    at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:110)
    at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:438)
Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; reason: {#method<channel.close>(reply-code=406,reply-text=PRECONDITION_FAILED - unknown delivery tag 1,class-id=60,method-id=80),null,""}
Run Code Online (Sandbox Code Playgroud)

scv*_*lex 25

可能导致该异常的唯一代码路径是通过处理'basic.ack'的代理,因此这听起来像客户端问题; 检查客户端代码.

特别是,检查您是否不止一次地发送消息.这样做违反了AMQP 0-9-1规范:

消息不得多次被确认.接收对等方必须验证非零传递标记是否指向已传递的消息,并且如果不是这种情况则引发通道异常

问这些问题的好地方是rabbitmq-discuss mainling-list; 所有RabbitMQ开发人员都阅读了该列表,并指出不会留下未回答的问题.

值得注意的是,以前版本的Rabbit更加宽松,并且在这种情况下没有抛出错误,但更新版本的确如此.

  • 我按照你的意见得到了来自RabbitMQ的马蒂亚斯的回答 - 我将在这里发表他的答案:我应该得到消息.因此订阅一个ack = true的频道 - > channel.basicConsume(queueName,true,queueingConsumer); .谢谢. (3认同)
  • 您能否发布更详细的答案,从您的评论中没有完全理解答案,谢谢。 (2认同)

Aut*_*oxy 5

刚刚成立noAck: falseBasicConsume方法