问题描述
我有一个Spring Boot应用程序,该应用程序连接到RabbitMQ集群(作为Cloud Foundry中的一项服务)。当群集中的主节点发生故障时,由于某种原因该节点无法启动,但是应用程序(消息使用者)尝试连接至故障节点,并且不尝试连接至其他可用节点。有人可以建议一些弹簧配置来解决此问题吗?
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)
'rabbit@rad33f2b1-mq-1.node.dc1.svvc'是失败的节点。
为了在失败时继续尝试连接到节点,我具有以下spring配置。 spring.rabbitmq.listener.simple.missing-queues-fatal = false
@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);
}
}
解决方法
当您使用具有错误主定位符的非HA自动删除队列时,会发生这种情况。
如果主定位器不是client-local
,则可能在与我们连接的节点不同的节点上创建自动删除队列。在这种情况下,如果主机节点出现故障,则会出现此问题。
为避免自动删除队列出现此问题,请将x-queue-master-locator
队列参数设置为client-local
或在代理上设置策略以对与此名称匹配的队列执行相同操作。
但是,您没有使用自动删除队列...
@Bean
public Queue failedOrderQueue(){
return new Queue(FAILED_ORDER_QUEUE_NAME);
}
在使用群集和非HA队列时,该队列不会被复制,因此,如果拥有节点发生故障,您将收到此错误,直到拥有节点恢复正常。
为避免此问题,请设置策略以使队列成为镜像(HA)队列。