首页 文章

具有 spring 的Rabbitmq群集在故障转移后不会失败

提问于
浏览
0

我使用spring-amqp连接到rabbitmq节点集群(A,B) . 此外,假设有两个消息接收器(Receiver_1和Receiver_2)正在使用与节点A的连接 .

当A发生故障时,Receiver_1和Receiver_2会自动切换连接以连接到B.假设A出现,然后群集中的B关闭 . 但是接收器不能再次消耗A.为什么?

我调试了 spring 项目,我发现它不是 spring 消费者的错误 . 事实上,spring确实切换到服务器“A”,但以下异常引发:

org.springframework.amqp.rabbit.listener.QueuesNotAvailableException:无法为侦听器准备队列 . 队列不存在或者代理不允许我们使用它 . at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:429)atg.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer $ AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1022)at java.lang.Thread .run(Unknown Source)引起:org.springframework.amqp.rabbit.listener.BlockingQueueConsumer $ DeclarationException:无法在org.springframework.amqp.rabbit.listener.BlockingQueueConsumer中声明队列:[ha.rabbit.channel2] .attemptPassiveDeclarations(BlockingQueueConsumer.java:486)org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:401)... 2更多

我检查了rabbidmq中的日志文件:

= ERROR REPORT ==== 2015年9月14日:: 03:45:41 ===连接时的通道错误<0.289.0>(192.168.1.150:64140 - > 192.168.1.170:5672,vhost:'/ ',user:'admin'), Channels 2:{amqp_error,not_found,'vhost'/'中持久队列'ha.rabbit.channel2'的主节点'rabbit @ vm2'已关闭或无法访问“,'queue.declare “}

即使我重新启动消费者应用程序,虽然之前的配置只是服务器A启动而B关闭,但同样的错误再次引发 . 我该如何解决?

1 回答

  • 1

    有一个open feature request for this .

    这并不容易,因为消费者特别是长寿,失败会导致处理中断(迫使消费者关闭和重新连接) .

    框架不知道何时这样做是“好”的时间 .

    您可以在 CachingConnectionFactory 上以编程方式调用 resetConnection() 以强制执行故障回复,但同样会影响现有的使用者 will . ( resetConnection() 在1.5中添加,在早期版本中调用 destroy() ) .

    也就是说,不清楚为什么这样的故障恢复是必要的,因为第二个服务器可能是HA队列的新主服务器,无论如何最好从那里消费 .

    因为默认情况下,只有一个连接用于所有客户端(在Spring AMQP中),所以将使用现有的故障转移连接,直到它失败 .

    您可以配置连接工厂以向每个用户分发不同的连接,并将缓存大小设置为1,但这实际上违背了缓存的整个目的 .

    EDIT

    另一种解决方案可能是编写另一个连接工厂,该工厂包装连接工厂的2个实例(每个实例配置一个地址) .

    然后,在 createConnection() 方法中,您可以"test"第一个连接并使用该连接(如果可用) .

    这将导致"new"用户(例如 RabbitTemplate )方法进行故障恢复,但它仍然无法解决监听器容器(消费者)的情况;您必须强制重置该连接才能使它们返回故障 .

相关问题