I have a Spring Boot application that supports Kafka. Recently I am trying to make it also support RabbitMQ. I set up the code using the @Profile
annotation so that all the new code for RabbitMQ should be active only if I select spring.profiles.active
to be rabbit-mq
. Likewise, the Kafka-specific code are marked out by profile value of kafka
I was surprise to see that even with the above setup, when I set the profile to be kafka
, some RabbitMQ is still included and activated, through a mechanism JMX exposure. Specifically, a rabbitConnectionFactory
bean was constructed, and then it tried to do health check with a RabbitMQ broker at localhost:5672
, and failed.
In the log file, I saw these messages:
... o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
... o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'rabbitConnectionFactory' has been autodetected for JMX exposure
... o.s.j.e.a.AnnotationMBeanExporter : Located managed bean 'rabbitConnectionFactory': registering with JMX server as MBean [org.springframework.amqp.rabbit.connection:name=rabbitConnectionFactory,type=CachingConnectionFactory]
... o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483547
... o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647
... o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
... c.s.datacomparatorproducer.Application : Started Application in 5.175 seconds (JVM running for 5.663)
... o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet'
... o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization started
... o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': initialization completed in 15 ms
... o.s.a.r.c.CachingConnectionFactory : Attempting to connect to: [localhost:5672]
... o.s.b.a.amqp.RabbitHealthIndicator : Rabbit health check failed
org.springframework.amqp.AmqpConnectException: java.net.ConnectException: Connection refused (Connection refused)
at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:62) ~[spring-rabbit-2.0.3.RELEASE.jar!/:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:476) ~[spring-rabbit-2.0.3.RELEASE.jar!/:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:614) ~[spring-rabbit-2.0.3.RELEASE.jar!/:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.createConnection(ConnectionFactoryUtils.java:240) ~[spring-rabbit-2.0.3.RELEASE.jar!/:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1797) ~[spring-rabbit-2.0.3.RELEASE.jar!/:2.0.3.RELEASE]
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1771) ~[spring-rabbit-2.0.3.RELEASE.jar!/:2.0.3.RELEASE]
I have two questions:
@Profile
did not work as expected?rabbitConnectionFactory
? Currently it is trying to talk to localhost:5672
. I know how to, in general, set up Spring template to use application-xxx.properties
for spring.rabbitmq.{host,port}
, but in this case, since the code is auto-included, I don't know how to configure rabbitConnectionFactory
Usual configuration
spring.rabbitmq.host=someRabbitBroker
spring.rabbitmq.port=5672
Update
Attempt 1: Excluding RabbitAutoConfiguration
Thank you Gary Russell for the suggestion. I tried his method and changed my @SpringBootApplication
as follows. The idea here is to exclude RabbitAutoConfiguration
when spring.rabbitmq.host
is NOT defined (when the profile of rabbit-mq
is not active):
@SpringBootApplication
public class Application {
@ConditionalOnProperty(value="spring.rabbitmq.host")
@Bean
RabbitAutoConfiguration rabbitAutoConfiguration(){
return new RabbitAutoConfiguration();
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
I am not sure if this code is the correct way to do it, but it did not work. When my app started, I still saw these in the message:
... o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
... o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'rabbitConnectionFactory' has been autodetected for JMX exposure
... o.s.j.e.a.AnnotationMBeanExporter : Located managed bean 'rabbitConnectionFactory': registering with JMX server as MBean [org.springframework.amqp.rabbit.connection:name=rabbitConnectionFactory,type=CachingConnectionFactory]
... o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483547
I am okay with having the bean constructed, as long as I can stop it from doing health check (or at least configure it to use my designated host and port). Is there a way to do this?
You either need to exclude the spring-rabbit jar from the classpath or disable rabbitmq auto-configuration by excluding RabbitAutoConfiguration
from the @SpringBootApplication
.
Update: disabling health check
See the boot properties documentation. Specifically set management.health.rabbit.enabled
to false