如何从Spring Boot Actuator健康检查中排除指定组件详情
问题:如何排除特定Bean的健康检查(IBM MQ的mqQueueConnectionFactory)
调用/actuator/health接口时,IBM MQ组件中的mqQueueConnectionFactory实例因缺少认证信息导致健康检查状态为DOWN,进而拉低整个JMS健康状态。该Bean无法移除,需要配置排除其健康检查。
当前健康检查结果
{ "status": "DOWN", "details": { "jms": { "status": "DOWN", "details": { "connectionFactory": { "status": "UP", "details": { "provider": "IBM MQ JMS Provider" } }, "queueConnectionFactory": { "status": "UP", "details": { "provider": "IBM MQ JMS Provider" } }, "mqQueueConnectionFactory": { "status": "DOWN", "details": { "error": "com.ibm.msg.client.jms.DetailedJMSSecurityException: JMSWMQ2013: The security authentication was not valid that was supplied for QueueManager 'GIMLI_A1' with connection mode 'Client' and host name 'gimli-a1.it.company.net(1417)'." } }, "userCredentialsConnectionFactoryAdapter": { "status": "UP", "details": { "provider": "IBM MQ JMS Provider" } }, "cachingConnectionFactory": { "status": "UP", "details": { "provider": "IBM MQ JMS Provider" } } } }, "db": { "status": "UP", "details": { "tnvet": { "status": "UP", "details": { "database": "DB2", "hello": 1 } }, "nk": { "status": "UP", "details": { "database": "DB2", "hello": 1 } } } } } }
环境信息
- Java版本: 8
- Spring Boot版本: 2.1.9.RELEASE
- Spring Boot Actuator版本: 2.1.9.RELEASE
- IBM MQ JMS Spring Boot Starter版本: 0.0.3
相关配置类
@Configuration public class AppConfiguration { @Value("${ibm.mq.hostName}") private String mqHostName; @Value("${ibm.mq.port}") private int mqPort; @Value("${ibm.mq.queueManager}") private String mqQueueManager; @Value("${ibm.mq.channel}") private String mqChannel; @Value("${ibm.mq.user}") private String mqUser; @Value("${ibm.mq.password}") private String mqPassword; @Bean public FilterRegistrationBean<CorsFilter> corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("*"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source)); bean.setOrder(Ordered.HIGHEST_PRECEDENCE); return bean; } @Bean public ConnectionFactory connectionFactory() throws JMSException { return userCredentialsConnectionFactoryAdapter(mqQueueConnectionFactory()); } @Bean public QueueConnectionFactory queueConnectionFactory() throws JMSException { return userCredentialsConnectionFactoryAdapter(mqQueueConnectionFactory()); } @Bean public MQQueueConnectionFactory mqQueueConnectionFactory() throws JMSException { MQQueueConnectionFactory cf = new MQQueueConnectionFactory(); // Get these settings from the application properties cf.setHostName(mqHostName); cf.setPort(mqPort); cf.setQueueManager(mqQueueManager); cf.setChannel(mqChannel); cf.setTransportType(CommonConstants.WMQ_CM_CLIENT); return cf; } @Bean(name = "jmsPlatformTransactionManager") public PlatformTransactionManager platformTransactionManager(CachingConnectionFactory cachingConnectionFactory) { cachingConnectionFactory.setCacheConsumers(true); cachingConnectionFactory.setSessionCacheSize(5); cachingConnectionFactory.setReconnectOnException(true); return new JmsTransactionManager(cachingConnectionFactory); } @Bean public DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactory(// PlatformTransactionManager jmsPlatformTransactionManager, // CachingConnectionFactory cachingConnectionFactory) { DefaultJmsListenerContainerFactory defaultJmsListenerContainerFactory = new DefaultJmsListenerContainerFactory(); defaultJmsListenerContainerFactory.setConnectionFactory(cachingConnectionFactory); defaultJmsListenerContainerFactory.setTransactionManager(jmsPlatformTransactionManager); defaultJmsListenerContainerFactory.setConcurrency("1-1"); defaultJmsListenerContainerFactory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE); defaultJmsListenerContainerFactory.setSessionTransacted(true); return defaultJmsListenerContainerFactory; } @Bean public UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter(MQQueueConnectionFactory mqQueueConnectionFactory) { UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter = new UserCredentialsConnectionFactoryAdapter(); userCredentialsConnectionFactoryAdapter.setUsername(mqUser); userCredentialsConnectionFactoryAdapter.setPassword(mqPassword); userCredentialsConnectionFactoryAdapter.setTargetConnectionFactory(mqQueueConnectionFactory); return userCredentialsConnectionFactoryAdapter; } @Bean public JmsListenerContainerFactory<DefaultMessageListenerContainer> myFactory(CachingConnectionFactory cachingConnectionFactory, DefaultJmsListenerContainerFactoryConfigurer configurer) { DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory(); factory.setSessionTransacted(false); factory.setConcurrency("1-1"); configurer.configure(factory, cachingConnectionFactory); return factory; } @Bean public CachingConnectionFactory cachingConnectionFactory(UserCredentialsConnectionFactoryAdapter userCredentialsConnectionFactoryAdapter) { CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory(); cachingConnectionFactory.setTargetConnectionFactory(userCredentialsConnectionFactoryAdapter); cachingConnectionFactory.setCacheConsumers(true); cachingConnectionFactory.setSessionCacheSize(5); cachingConnectionFactory.setCacheProducers(true); cachingConnectionFactory.setReconnectOnException(true); return cachingConnectionFactory; } @Bean public JmsOperations jmsOperations(CachingConnectionFactory cachingConnectionFactory) { JmsTemplate jmsTemplate = new JmsTemplate(cachingConnectionFactory); jmsTemplate.setReceiveTimeout(10); return jmsTemplate; } @Bean public RestTemplate restTemplate() { return new RestTemplate(); } }
解决方案
针对Spring Boot 2.1.x版本,推荐以下方式排除指定Bean的健康检查:
方式一:自定义JmsHealthIndicator
默认的JmsHealthIndicator会检测所有ConnectionFactory类型的Bean,我们可以自定义一个健康检查器,移除不需要检查的mqQueueConnectionFactory:
import org.springframework.boot.actuate.health.Health; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.actuate.jms.JmsHealthIndicator; import org.springframework.jms.connection.ConnectionFactory; import org.springframework.stereotype.Component; import java.util.Map; @Component("jms") public class CustomJmsHealthIndicator implements HealthIndicator { private final JmsHealthIndicator delegate; public CustomJmsHealthIndicator(Map<String, ConnectionFactory> connectionFactories) { // 移除不需要检查的ConnectionFactory实例 connectionFactories.remove("mqQueueConnectionFactory"); this.delegate = new JmsHealthIndicator(connectionFactories); } @Override public Health health() { return this.delegate.health(); } }
说明
- 自定义的Indicator名称设为
jms,会自动覆盖默认的JMS健康检查器 - 重启应用后,调用
/actuator/health即可看到mqQueueConnectionFactory不再出现在JMS健康详情中,整体JMS状态会变为UP
内容的提问来源于stack exchange,提问作者BT_Code
相关产品推荐
相关产品推荐

