问题描述
我有一个基于SpringBoot的Web应用程序,它公开了领事健康指示符bean。
通过springboot的自动配置可以正确创建和初始化该Bean,但是尽管已将关联的配置属性“ management.health.consul.enabled”设置为true,该指示符仍未在执行器运行状况端点中显示:
{
"status": "UP","components": {
"Kafka": {...},"SchemaRegistry": {...},"discoveryComposite": {...},"diskSpace": {...},"ping": {...},"refreshScope": {...}
}
}
进一步检查后,我发现波纹管片段负责获取所有可用的指标(HealthEndpointConfiguration.java):
@Bean
@ConditionalOnMissingBean
HealthContributorRegistry healthContributorRegistry(ApplicationContext applicationContext,HealthEndpointGroups groups) {
Map<String,HealthContributor> healthContributors = new LinkedHashMap<>(
applicationContext.getBeansOfType(HealthContributor.class));
if (ClassUtils.isPresent("reactor.core.publisher.Flux",applicationContext.getClassLoader())) {
healthContributors.putAll(new AdaptedReactiveHealthContributors(applicationContext).get());
}
return new AutoConfiguredHealthContributorRegistry(healthContributors,groups.getNames());
}
在此处设置一个断点,我确实发现ConsulHealthindicator bean确实没有在 applicationContext.getBeansOfType(HealthContributor.class)调用的输出中列出,如下所示:
有人可以阐明为什么这种特定的豆出现在root context而不是child context中的原因吗?
是否有一种方法可以强制在子上下文中对其进行初始化,以使其在运行状况端点中正确注册?
我当前正在使用
- SpringBoot 2.3.1发行版
- spring-cloud-starter-consul-all 2.2.4.RELEASE
谢谢。
编辑
我已附上a sample project,允许复制该问题。
我还提供了应用程序使用的consul配置(您可以通过consul import命令将其导入)。
运行上面的示例并转到运行状况端点(localhost:8080 / monitoring / health),您将清楚地看到列表中缺少领事组件。
解决方法
为了使领事指示符正常工作,我必须提供自己的HealthContributorRegistry,在执行HealthContributor Bean查找时要在其中考虑父上下文:
@Bean
HealthContributorRegistry healthContributorRegistry(
ApplicationContext applicationContext,HealthEndpointGroups groups) {
Map<String,HealthContributor> healthContributors =
new LinkedHashMap<>(applicationContext.getBeansOfType(HealthContributor.class));
ApplicationContext parent = applicationContext.getParent();
while (parent != null) {
healthContributors.putAll(parent.getBeansOfType(HealthContributor.class));
parent = parent.getParent();
}
return new DefaultHealthContributorRegistry(healthContributors);
}
这是一个临时解决方法,理想情况下,领事指示器应该像其他健康贡献者一样开箱即用。