首页 > 解决方案 > 启动期间未调用自定义 HealthIndicator

问题描述

HealthIndicator为我们的应用程序实现了一个自定义,它工作正常。

我注意到,当我通过我的 IDE(使用 IntelliJ 和 Eclipse 测试)运行应用程序时,该HealthIndicator.health()方法在启动期间被调用。

但是,当我使用 JAR 文件本身运行应用程序时,HealthIndicator.health()在应用程序启动期间不会调用该方法。

HealthIndicator.health()当我将它作为 JAR 文件运行时,为什么在启动期间没有调用该方法,并且它的行为不应该与通过 IDE 运行它时相似?

标签: spring-bootspring-boot-actuator

解决方案


这实际上并不是真正的错误,而是由您的 IDE 引起的副作用。您应该知道,Actuator 端点不仅通过 HTTP 公开,还通过 JMX 公开。如果您查看文档,您还会看到默认情况下在 HTTP 和 JMX 上都启用了健康端点。

此外,大多数 IDE,包括 IntelliJ 和 Eclipse,将在通过 IDE 本身运行应用程序时启用 JMX 代理。这意味着当应用程序启动时,会建立一个 JMX 连接,进而触发自定义运行状况指示器。

您可以很容易地验证这一点,例如让我们假设以下健康指标:

@Bean
public HealthIndicator alwaysUpHealthIndicator() {
    return () -> {
        log.info("Indicator invoked");
        return Health.up().withDetail("Foo", "Bar").build();
    };
}

如果您更改 IntelliJ 运行配置并禁用Enable JMX agent,您会注意到该消息不再出现在日志中。

IntelliJ 配置截图

同样,如果您禁用运行状况 JMX 端点,您还会注意到您不会在日志中收到其他消息:

management.endpoints.jmx.exposure.exclude=health

这意味着您不应该依赖在HealthIndicator应用程序启动期间执行的操作。如果您的应用程序启动时应该执行代码,请考虑使用ApplicationRunneror CommandLineRunnerbean。例如:

@Bean
public ApplicationRunner applicationRunner() {
    return args -> log.info("This will be invoked on startup");
}

推荐阅读