我们使用spring-amqp库来使用来自RabbitMQ的消息,有时当我们处理消息时,我们遇到了以下异常:
org.springframework.amqp.AmqpException: PublisherCallbackChannel is closed
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:908)
at com.sun.proxy.$Proxy265.basicAck(Unknown Source)
at com.zeus.server.queue.AbstractBatchingQueueMessageListener.ackBatch(AbstractBatchingQueueMessageListener.java:105)
at com.zeus.server.queue.AbstractBatchingQueueMessageListener.executeBatch(AbstractBatchingQueueMessageListener.java:88)
at com.zeus.server.queue.AbstractBatchingQueueMessageListener.access$300(AbstractBatchingQueueMessageListener.java:27)
at com.zeus.server.queue.AbstractBatchingQueueMessageListener$BatchExecutor.run(AbstractBatchingQueueMessageListener.java:161)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
有什么想法吗?
供参考:我们正在使用RabbitMQ 3.5.6& spring-amqp:1.6.1.RELEASE
答案 0 :(得分:1)
@ArtemBilan提到的5秒延迟是在实际结束后保持频道开放的缓冲,以防有待收到的发布者确认。 5秒就足够了。
这里没有任何关系;监听器容器在关闭之前不要关闭它们的通道,即使这样,关闭也是在监听器线程退出方法后完成的。
如果您在寻找时遇到频道关闭错误,则意味着其他方式关闭了频道;也许是一个连接掉线。
我建议你先在日志和/或兔子服务器日志中查看是否有任何线索。
1.6.1已将近2岁。
如果刚刚开始发生这种情况,我怀疑app / environment中的其他内容已经发生了变化。
我认为你的并发性是1 - 否则你所做的很糟糕,因为每个线程都有自己的通道。
修改强>
我刚注意到你正在使用遗嘱执行人 - 你不能这样做;通道不是线程安全的;你应该在监听器线程上执行批处理。
at com.zeus.server.queue.AbstractBatchingQueueMessageListener.ackBatch(AbstractBatchingQueueMessageListener.java:105)
at com.zeus.server.queue.AbstractBatchingQueueMessageListener.executeBatch(AbstractBatchingQueueMessageListener.java:88)
at com.zeus.server.queue.AbstractBatchingQueueMessageListener.access$300(AbstractBatchingQueueMessageListener.java:27)
at com.zeus.server.queue.AbstractBatchingQueueMessageListener$BatchExecutor.run(AbstractBatchingQueueMessageListener.java:161)
答案 1 :(得分:0)
我遇到此问题是因为代码中的两次确认:
if(null != jsonObject){
//some code
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
}
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
只需删除第一个确认即可解决我的问题!