启动期间未调用自定义HealthIndicator

时间:2019-06-25 07:13:45

标签: spring-boot spring-boot-actuator

我为我们的应用程序实现了自定义HealthIndicator,效果很好。

我注意到,当我通过IDE(经IntelliJ和Eclipse测试)运行应用程序时,在启动过程中将调用HealthIndicator.health()方法。

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

为什么当我将其作为JAR文件运行时,在启动过程中未调用HealthIndicator.health()方法,并且它的行为不应该与通过IDE运行它时的行为类似吗?

2 个答案:

答案 0 :(得分:1)

这实际上不是错误,而是由您的IDE引起的副作用。您应该意识到,Actuator端点不仅通过HTTP公开,而且通过JMX公开。如果您查看the documentation,还将看到默认情况下,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运行配置并禁用启用JMX代理,则会注意到该消息不再出现在日志中。

Screenshot of IntelliJ configuration

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

management.endpoints.jmx.exposure.exclude=health

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

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

答案 1 :(得分:0)

我无法直接回答问题,但似乎这里没有真正的问题,如果它是错误的,请向Spring Boot团队提交错误。否则,这只是我完全同意的说法。

  

应该以两种方式执行HelathIndicator health()方法,或者根本不执行。

您描述的内容听起来更像是一个怪异的错误,这是一种检查发生情况的肮脏方法(将其删除或在生产过程中进行):

运行状况指示器的health方法内部获取堆栈跟踪并将其打印在控制台上。 分析堆栈跟踪,并检查其是否不是通过HTTP进行某些/ health调用的结果(例如,您的IDE配置为在启动时自动调用执行器的运行状况,谁知道)