🍀SpringBoot:项目集成 RabbitMQ 启动报错
在 Springboot 项目中,集成了RabbitMQ,集群A的配置如下:
rabbitmq.public.host = 101.1.1.1
rabbitmq.public.port = 25672
rabbitmq.public.username = user
rabbitmq.public.password = user@PassWord
但是当项目启动时报错:
ms-service 2025-03-28 09:31:22.227 [SimpleAsyncTaskExecutor-197] [,,,] INFO o.s.a.r.c.CachingConnectionFactory - Attempting to connect to: [101.1.1.1]
ms-service 2025-03-28 09:31:22.227 [DiscoveryClient-InstanceInfoReplicator-0] [,,,] WARN o.s.b.a.a.RabbitHealthIndicator - Rabbit health check failed
org.springframework.amqp.AmqpIOException: java.net.SocketTimeoutException: connect timed out
at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:71)
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:476)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:614)
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.createConnection(ConnectionFactoryUtils.java:240)
at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1797)
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1771)
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1752)
at org.springframework.boot.actuate.amqp.RabbitHealthIndicator.getVersion(RabbitHealthIndicator.java:48)
at org.springframework.boot.actuate.amqp.RabbitHealthIndicator.doHealthCheck(RabbitHealthIndicator.java:44)
at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.java:84)
at org.springframework.boot.actuate.health.CompositeHealthIndicator.health(CompositeHealthIndicator.java:68)
at org.springframework.cloud.netflix.eureka.EurekaHealthCheckHandler.getHealthStatus(EurekaHealthCheckHandler.java:103)
at org.springframework.cloud.netflix.eureka.EurekaHealthCheckHandler.getStatus(EurekaHealthCheckHandler.java:99)
at com.netflix.discovery.DiscoveryClient.refreshInstanceInfo(DiscoveryClient.java:1382)
at com.netflix.discovery.InstanceInfoReplicator.run(InstanceInfoReplicator.java:117)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.net.SocketTimeoutException: connect timed out
at java.net.PlainSocketImpl.socketConnect(Native Method)
经过排查可以确定,MQ的配置信息时没有问题的
然后我讲配置信息换成集群B
rabbitmq.public.host = 101.1.1.2
rabbitmq.public.port = 5672
rabbitmq.public.username = user
rabbitmq.public.password = user@PassWord
项目就可以正常启动
ms-service 2025-03-28 09:36:11.864 [DiscoveryClient-InstanceInfoReplicator-0] [,,,] INFO o.s.a.r.c.CachingConnectionFactory - Attempting to connect to: [101.1.1.2]
ms-service 2025-03-28 09:36:11.912 [main] [,,,] INFO s.d.s.w.s.ApiListingReferenceScanner - Scanning for api listing references
ms-service 2025-03-28 09:36:12.143 [DiscoveryClient-InstanceInfoReplicator-0] [,,,] INFO o.s.a.r.c.CachingConnectionFactory - Created new connection: rabbitConnectionFactory#795bc4b8:0/SimpleConnection@8aa9094 [delegate=amqp://user@101.1.1.2:5672/, localPort= 50742]
从配置看两个集群只有端口不一致,通过命令查看MQ IP占用情况发现,集群A的配置端口虽然是25672,但是服务器连的却是5672
netstat -an | grep 101.1.1.1
连接工厂代码如下:
@Bean("rabbitConnectionFactory")
public ConnectionFactory mqConnectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
connectionFactory.setPublisherConfirms(true);
connectionFactory.setAddresses(host);
connectionFactory.setPort(port);
return connectionFactory;
}
这段代码在配置host时使用了 `connectionFactory.setAddresses(host);` ,通过查看这段代码的源代码发现,它会重写配置,传入的格式为:host[:port],如果没有port,会默认赋值 5672
解决方案就是,使用setHost方法
@Bean("rabbitConnectionFactory")
public ConnectionFactory mqConnectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtualHost);
connectionFactory.setPublisherConfirms(true);
connectionFactory.setHost(host);
connectionFactory.setPort(port);
return connectionFactory;
}
License:
CC BY 4.0