Java RabbitMQ群集节点在spring引导应用程序中出现故障
我有一个spring引导应用程序,它连接到RabbitMQ集群(作为CloudFoundry中的服务)。当群集中的主节点出现故障,并且由于某种原因,该节点无法启动,但应用程序(消息使用者)正在尝试连接到故障节点,并且没有尝试连接到其他可用节点时。有人能推荐一些spring配置来解决这个问题吗Java RabbitMQ群集节点在spring引导应用程序中出现故障,java,spring-boot,rabbitmq,cloud-foundry,spring-rabbit,Java,Spring Boot,Rabbitmq,Cloud Foundry,Spring Rabbit,我有一个spring引导应用程序,它连接到RabbitMQ集群(作为CloudFoundry中的服务)。当群集中的主节点出现故障,并且由于某种原因,该节点无法启动,但应用程序(消息使用者)正在尝试连接到故障节点,并且没有尝试连接到其他可用节点时。有人能推荐一些spring配置来解决这个问题吗 17:36:23.829: [APP/PROC/WEB.0] Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; p
17:36:23.829: [APP/PROC/WEB.0] Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=404, reply-text=NOT_FOUND - home node 'rabbit@rad33f2b1-mq-1.node.dc1.svvc' of durable queue 'FAILED_ORDER' in vhost '/' is down or inaccessible, class-id=50, method-id=10)
}当您使用的非HA自动删除队列的主定位器不正确时,可能会发生这种情况 如果主定位器不是
客户机本地
,则可能会在与我们连接的节点不同的节点上创建自动删除队列。在这种情况下,如果主机节点发生故障,您将遇到此问题
要避免自动删除队列出现此问题,请将x-queue-master-locator
队列参数设置为client local
,或在代理上设置策略,以便对匹配此名称的队列执行相同操作
但是,您没有使用自动删除队列
@Bean
公共队列失败OrderQueue(){
返回新队列(失败的\u订单\u队列\u名称);
}
当使用集群和非HA队列时,队列不会被复制,因此,如果所属节点停机,您将收到此错误,直到所属节点恢复
要避免此问题,请设置一个策略,使队列成为镜像(HA)队列
谢谢您的回复。镜像HA在RabbitMQ中启用,我分别检查了每个节点的队列,它也可用。在我看来,当主节点出现故障时,Spring引导应用程序不会尝试下一个节点。这根本不是真的<代码>>回复代码=404,回复文本=未找到-主节点'rabbit@rad33f2b1-vhost“/”中持久队列“FAILED_ORDER”的mq-1.node.dc1.svvc已关闭或无法访问表示应用程序已连接到群集,但代理正在重新返回此错误,因为承载该队列的节点已关闭,这意味着此特定队列未被镜像,在其主主机恢复联机之前无法从中使用。通常,Spring会在3次此类故障后放弃
missingQueuesFatal=false
表示永远尝试。查看您的HA策略,了解为什么它没有镜像。
@Configuration
public class MessageConfiguration {
public static final String FAILED_ORDER_QUEUE_NAME = "FAILED_ORDER";
public static final String EXCHANGE = "directExchange";
@Bean
public Queue failedOrderQueue(){
return new Queue(FAILED_ORDER_QUEUE_NAME);
}
@Bean
public DirectExchange directExchange(){
return new DirectExchange(EXCHANGE,true,false);
}
@Bean
public Binding secondBinding(Queue failedOrderQueue, DirectExchange directExchange){
return BindingBuilder.bind(failedOrderQueue).to(directExchange).with(FAILED_ORDER_QUEUE_NAME);
}