【问题标题】:Disable and Replace Default DataSourceHealthIndicator禁用和替换默认 DataSourceHealthIndicator
【发布时间】:2016-08-16 17:26:11
【问题描述】:

我目前正在使用使用 Spring Boot Actuator“健康”端点实现的健康监控框架。 Actuator 基础设施支持创建自定义健康检查,还提供了许多内置的健康检查;其中之一是DataSourceHealthIndicator

DataSourceHealthIndicatororg.springframework.boot.actuate.health 包的一部分,目前我们的健康框架使用它来检查数据源的健康状况。我需要使用我自己的、稍加修改的DataSourceHealthIndicator 版本并禁用“默认”。

我已经尝试了herehere 建议的解决方案,但没有成功。我可能做错了什么?

谢谢!


编辑:2016 年 8 月 18 日,美国东部标准时间下午 3:38

我已将我的 bean 重命名为 dbHealthIndicator 并将以下内容添加到我的配置类中:

@Bean
public HealthIndicator dbHealthIndicator() {
     return new dbHealthIndicator();
}

我现在遇到以下异常:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataAccessMapperFactory' defined in class path resource [udtContext.xml]

java.lang.RuntimeException: java.sql.SQLException: Unable to start the Universal Connection Pool: oracle.ucp.UniversalConnectionPoolException


编辑:2016 年 8 月 19 日,美国东部标准时间上午 9:22

这可能有助于展示我正在尝试做的事情。目前,我的 /health 端点返回如下所示的内容:

dataSource: {
     status: "UP",
     database: "mySql",
     hello: "hello"
}

我希望它返回更像这样的东西,其中“结果”旁边的整数是我的数据库中的存储过程返回的状态代码:

dataSource: {
     status: "UP",
     database: "mySql",
     hello: "hello",
     result: 0
}

这是DataSourceHealthIndicator.java 中执行检查的方法:

private void doDataSourceHealthCheck(Health.Builder builder) throws Exception {
    String product = getProduct();
    builder.up().withDetail("database", product);
    String validationQuery = getValidationQuery(product);
    if (StringUtils.hasText(validationQuery)) {
        try {
            // Avoid calling getObject as it breaks MySQL on Java 7
            List<Object> results = this.jdbcTemplate.query(validationQuery,
                    new SingleColumnRowMapper());
            Object result = DataAccessUtils.requiredSingleResult(results);
            builder.withDetail("hello", result);
        }
        catch (Exception ex) {
            builder.down(ex);
        }
    }
}

我需要在这个方法中添加八行代码,在builder.withDetail("hello", result); 下,以执行对存储过程的调用。我不想“反编译”默认类,并且我无法覆盖此方法,因为它是私有的。我在想我可以在我自己的 bean 中复制 DataSourceHealthIndicator.java 代码,添加我的代码,然后重新连接 Spring 以使用这个版本,但我不知道这是否可能。

【问题讨论】:

  • 你为什么需要你自己的HealthIndicator 是什么你正在尝试做的事情在原来的那个不起作用/不起作用?
  • M. Deinum,我希望覆盖或扩展内置 DataSourceHealthIndicator 中的 doDataSourceHealthCheck() 方法来调用我数据库中的存储过程;但是,Java 不支持覆盖或扩展私有方法。所以,我所做的是复制 DataSourceHealthIndicator 并在我自己的自定义 bean 中添加大约八行代码。我想使用这个“扩展”版本而不是默认版本。你知道这是否可能吗?
  • 但是你真的想禁用默认的,还是这个附加信息?你的行不通,我希望您尝试在自己的实现中使用自动装配,但这是行不通的。看一下原始的健康指标(它得到了一个DataSource,它应该由构造函数传入)。你也应该构造它。但是我怀疑你想用你的替换现有的,我猜你想要两个......
  • M. Deinum,谢谢你的帮助!我已经编辑了我的原始帖子,以包含有关我正在尝试做的事情的更多信息。
  • 我仍然不明白为什么建议的解决方案不起作用。这些还清楚地表明您需要注入数据源。您没有在您的健康指标中注入任何东西。所以我怀疑你正在使用自动装配,但它失败了,因为这发生在这个过程的早期。

标签: java spring spring-boot health-monitoring spring-boot-actuator


【解决方案1】:

通常我会查看HealthIndicator 的配置。在这种情况下,它是HealthIndicatorAutoConfiguration.DataSourcesHealthIndicatorConfiguration。正如第一个链接的建议所述。您需要将自定义 bean 命名为 dbHealthIndicator,以便 @ConditionalOnMissingBean(name = "dbHealthIndicator") 不允许注册默认值。

提供一些启动日志或不适合您的详细信息将有助于人们进行故障排除。

这是我如何让它工作的示例:

@SpringBootApplication
public class StackoverflowWebmvcSandboxApplication {
    @Bean
    public HealthIndicator dbHealthIndicator() {
        return new HealthIndicator() {

            @Override
            public Health health() {
                return Health.status(Status.UP).withDetail("hello", "hi").build();
            }
        };
    }

    public static void main(String[] args) {
        SpringApplication.run(StackoverflowWebmvcSandboxApplication.class, args);
    }

    @RestController
    public class HelloController {
        @GetMapping("/hello")
        public String hello() {
            return "hello";
        }
    }
}

/health 端点随后返回:

{
    "status": "UP",
    "db": {
        "status": "UP",
        "hello": "hi"
    },
    "diskSpace": {
        "status": "UP",
        "total": 127927316480,
        "free": 17191956480,
        "threshold": 10485760
    }
}

【讨论】:

  • 感谢您的帮助,肖恩!更详细一点,即使我将自定义 bean 重命名为 dbHealthIndicator,框架似乎仍然使用默认值(不返回错误消息)。是否需要进行任何其他配置或“重新布线”才能注册我的健康检查?
  • Shawn,我已经编辑了我的原始帖子以包含我的 bean 配置代码,以及我现在遇到的异常。
  • 启动日志是否显示该 bean 正在实例化以在上下文中使用?
  • 我目前正在查看日志——与此同时,除了重命名 bean 和添加我需要做的上述代码之外,是否还有其他配置? (我认为我对 Spring 的缺乏经验开始表现出来了!)
  • 我回家后会尝试自己,但根据我在文档中阅读的内容以及看起来你的方式应该可行的代码
猜你喜欢
  • 2016-12-13
  • 1970-01-01
  • 2018-06-11
  • 1970-01-01
  • 2017-02-12
  • 2014-03-28
  • 2012-09-04
  • 1970-01-01
  • 2016-11-28
相关资源
最近更新 更多