为什么我的 Spring 带有 SQS 的启动应用程序不显示 JMSHealthIndicator?

Why is my Spring Boot app with SQS Not Showing a JMSHealthIndicator?

我正在开发一个 Spring 引导应用程序,它按照 post https://aws.amazon.com/blogs/developer/using-amazon-sqs-with-spring-boot-and-spring-jms/

中的描述从 SQS 获取消息

当我在 localhost:8081/health 访问内置的 Spring 启动健康端点时,我希望看到一些关于 JMS 代理的信息,因为 Spring Boot docs 说有自动配置的健康指标都配置了"when appropriate"其中一个是JmsHealthIndicator。相反,我只看到状态和磁盘空间 {"status":"UP","diskSpace":{"status":"UP","total":31572619264,"free":24611381248,"threshold":10485760}}

有谁知道为什么我们在运行状况端点上看不到有关 JMS 的任何信息?该应用程序可以很好地从 SQS 读取,但由于它托管在 Kubernetes 中,我想添加一个 readiness/liveness 探测并在检查中包含 JMS。

有关 @EnableJms 的 JMS 配置信息如下

import javax.jms.Session;

import com.amazon.sqs.javamessaging.SQSConnectionFactory;
import com.amazonaws.auth.AWSCredentialsProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.aws.core.region.RegionProvider;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.support.destination.DynamicDestinationResolver;

@Configuration
@EnableJms
public class JmsConfig {

private static final Logger LOGGER = LoggerFactory.getLogger(JmsConfig.class);
private static final String LOWER_UPPER_CONCURRENCY = "3-10";

private final SQSConnectionFactory connectionFactory;

public JmsConfig(RegionProvider regionProvider, AWSCredentialsProvider awsCredentialsProvider) {
    this.connectionFactory = SQSConnectionFactory.builder()
            .withRegion(regionProvider.getRegion())
            .withAWSCredentialsProvider(awsCredentialsProvider)
            .build();
    LOGGER.info("Loading JmsConfig");
}

@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory() {
    DefaultJmsListenerContainerFactory factory =
            new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(this.connectionFactory);
    factory.setDestinationResolver(new DynamicDestinationResolver());
    factory.setConcurrency(LOWER_UPPER_CONCURRENCY);
    factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
    return factory;
}

@Bean
public JmsTemplate defaultJmsTemplate() {
    return new JmsTemplate(this.connectionFactory);
}

}

然后我们还有一个注解为@JmsListener(destination = "${sqs.input.queue}")

的方法

编辑:请注意,我已经尝试将以下内容添加到 application.properties

management.health.defaults.enabled=true
management.health.jms.enabled=true
endpoints.health.sensitive=false

谢谢, 丽安.

我认为您可能需要在 application.properties 文件中再添加一个 属性:

management.security.enabled=false

根据文档:

By default all sensitive HTTP endpoints are secured such that only users that have an ACTUATOR role may access them. Security is enforced using the standard HttpServletRequest.isUserInRole method

If you are deploying applications behind a firewall, you may prefer that all your actuator endpoints can be accessed without requiring authentication. You can do this by changing the management.security.enabled property

在此处查看更多相关信息:https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-monitoring.html

事实证明,将连接工厂作为 bean 公开现在会导致运行状况响应中出现 JMS 部分。

因此,将代码更改为

@Configuration
@EnableJms
public class JmsConfig {

private static final Logger LOGGER = LoggerFactory.getLogger(JmsConfig.class);
private static final String LOWER_UPPER_CONCURRENCY = "3-10";

public JmsConfig() {
    LOGGER.info("Loading JmsConfig");
}

@Bean
public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(SQSConnectionFactory connectionFactory) {
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    factory.setDestinationResolver(new DynamicDestinationResolver());
    factory.setConcurrency(LOWER_UPPER_CONCURRENCY);
    factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
    return factory;
}

@Bean
public SQSConnectionFactory sqsConnectionFactory(RegionProvider regionProvider, AWSCredentialsProvider awsCredentialsProvider) {
    return SQSConnectionFactory.builder()
            .withRegion(regionProvider.getRegion())
            .withAWSCredentialsProvider(awsCredentialsProvider)
            .build();
}

@Bean
public JmsTemplate defaultJmsTemplate(SQSConnectionFactory connectionFactory) {
    return new JmsTemplate(connectionFactory);
}

}

健康端点响应如下所示

{
"status": "UP",
"jms": {
    "status": "UP",
    "provider": "Amazon"
},
"diskSpace": {
    "status": "UP",
    "total": 249779191808,
    "free": 165159432192,
    "threshold": 10485760
}
}

一位同事在看到 JmsHealthIndicator 的构造函数后有一种预感,连接工厂无法访问。