Consul健康指示器在Spring Boot的执行器健康端点中未显示。

huangapple go评论92阅读模式
英文:

Consul Health indicator not showing in SpringBoot' actuator health endpoint

问题

我有一个基于SpringBoot的Web应用程序,暴露了一个Consul健康指示器(health indicator)bean。
该bean由SpringBoot的自动配置正确创建和初始化,然而,尽管相关的配置属性“management.health.consul.enabled”被设置为true,但该指示器在执行器(actuator)健康端点中没有显示:

{
   "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)的输出中,如下所示:

(截图无法在文本中显示,无法提供图片)

但是当我使用父应用程序上下文测试相同的调用时,我得到以下结果:

(截图无法在文本中显示,无法提供图片)

有人可以解释一下为什么这个特定的bean存在于根上下文但不存在于子上下文中吗?

是否有一种方法可以强制在子上下文中初始化它,以便它可以正确地注册在健康端点中?

我附上了一个示例项目,可以重现这个问题。我还包括了应用程序使用的Consul配置示例(您可以通过consul import命令导入它)。
运行上面的示例并转到健康端点(localhost:8080/monitoring/health),您将清楚地看到列表中缺少Consul组件。

提前感谢您的帮助。

英文:

I have a SpringBoot based web application that exposes a consul health indicator bean.
The bean is correctly created and initialized by springboot's autoconfiguration, yet, the indicator is not showing in the actuator health endpoint despite the fact that the associated configuration property "management.health.consul.enabled" is set to true:

{
   &quot;status&quot;: &quot;UP&quot;,
   &quot;components&quot;: {
        &quot;Kafka&quot;: {...},
        &quot;SchemaRegistry&quot;: {...},
        &quot;discoveryComposite&quot;: {...},
        &quot;diskSpace&quot;: {...},
        &quot;ping&quot;: {...},
        &quot;refreshScope&quot;: {...}
    }
}

Upon further inspection, I found the bellow snippet that is responsible for fetching all the available indicators (HealthEndpointConfiguration.java) :

    @Bean
	@ConditionalOnMissingBean
	HealthContributorRegistry healthContributorRegistry(ApplicationContext applicationContext,
			HealthEndpointGroups groups) {
		Map&lt;String, HealthContributor&gt; healthContributors = new LinkedHashMap&lt;&gt;(
				applicationContext.getBeansOfType(HealthContributor.class));
		if (ClassUtils.isPresent(&quot;reactor.core.publisher.Flux&quot;, applicationContext.getClassLoader())) {
			healthContributors.putAll(new AdaptedReactiveHealthContributors(applicationContext).get());
		}
		return new AutoConfiguredHealthContributorRegistry(healthContributors, groups.getNames());
	}

Setting a break point there, I see that indeed the ConsulHealthIndicator bean is not listed in the output of the applicationContext.getBeansOfType(HealthContributor.class) call as shows bellow :

Consul健康指示器在Spring Boot的执行器健康端点中未显示。

But when I test the same call with the parent application context instead, I get the following :
Consul健康指示器在Spring Boot的执行器健康端点中未显示。

Can someone please shed some light on why this particular bean is present in the root context but not in the child context ?

Is there a way to force it's initialisation in the child context so that it will get correctly registered in the health endpoint ?

I've attached a sample project allowing the reproduction of the issue. I've also included a sample of consul configuration that is used by the app (you can import it via consul import command).
Running the example above and going to the health endpoint (localhost:8080/monitoring/health) you will clearly see that the consul component is missing from the list.

Thank you in advance.

答案1

得分: 0

如现在所示,Consul 健康指示器未注册到健康贡献者注册表中,您可以通过自行注册 Consul 健康检查来解决这个问题。您可以在任何配置文件中添加类似以下内容的代码片段。

@Autowired
public void doRegister(
    ConsulHealthIndicator healthIndicator, HealthContributorRegistry healthContributorRegistry) {
  healthContributorRegistry.registerContributor("consul", healthIndicator);
}

一旦添加了这个代码片段,应该会产生类似以下的输出。

{
  "status": "UP",
  "components": {
    "consul": {
      "status": "UP",
      "details": {
        "leader": "127.0.0.1:8300",
        "services": {
          "consul": []
        }
      }
    },
    "discoveryComposite": {
      "description": "Discovery Client not initialized",
      "status": "UNKNOWN",
      "components": {
        "discoveryClient": {
          "description": "Discovery Client not initialized",
          "status": "UNKNOWN"
        }
      }
    },
    "diskSpace": {
      "status": "UP",
      "details": {
        "total": 250685575168,
        "free": 17967964160,
        "threshold": 10485760,
        "exists": true
      }
    },
    "ping": {
      "status": "UP"
    },
    "refreshScope": {
      "status": "UP"
    }
  }
}
英文:

As it seems, the Consul health indicator is not registered to the health contributor registry, you can work around this by registering the consul health check by your self. You can add a snippet like this in any configuration file.

@Autowired
  public void doRegister(
      ConsulHealthIndicator healthIndicator, HealthContributorRegistry healthContributorRegistry) {
    healthContributorRegistry.registerContributor(&quot;consul&quot;, healthIndicator);
  }

Once added this should produce something like this

{
  &quot;status&quot;: &quot;UP&quot;,
  &quot;components&quot;: {
    &quot;consul&quot;: {
      &quot;status&quot;: &quot;UP&quot;,
      &quot;details&quot;: {
        &quot;leader&quot;: &quot;127.0.0.1:8300&quot;,
        &quot;services&quot;: {
          &quot;consul&quot;: []
        }
      }
    },
    &quot;discoveryComposite&quot;: {
      &quot;description&quot;: &quot;Discovery Client not initialized&quot;,
      &quot;status&quot;: &quot;UNKNOWN&quot;,
      &quot;components&quot;: {
        &quot;discoveryClient&quot;: {
          &quot;description&quot;: &quot;Discovery Client not initialized&quot;,
          &quot;status&quot;: &quot;UNKNOWN&quot;
        }
      }
    },
    &quot;diskSpace&quot;: {
      &quot;status&quot;: &quot;UP&quot;,
      &quot;details&quot;: {
        &quot;total&quot;: 250685575168,
        &quot;free&quot;: 17967964160,
        &quot;threshold&quot;: 10485760,
        &quot;exists&quot;: true
      }
    },
    &quot;ping&quot;: {
      &quot;status&quot;: &quot;UP&quot;
    },
    &quot;refreshScope&quot;: {
      &quot;status&quot;: &quot;UP&quot;
    }
  }
}

huangapple
  • 本文由 发表于 2020年8月21日 15:43:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/63518618.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定