【问题标题】:Shutown Spring when DB is lostDB丢失时关闭Spring
【发布时间】:2022-05-17 14:36:44
【问题描述】:

用例

我们的 spring-boot-backend (v 2.3.1) 使用带有 HikariCP 作为连接池的 postgres 数据库。
应用程序在线,管理员不小心杀死了数据库。

预期行为

Spring 注意到与 DB 的连接已丢失。应用程序将正常关闭。

实际行为

春天仍在运行。所有需要数据库的方法都以异常结束。
要恢复完全好的状态,我们需要手动重启spring。

备注
我们有很多异步工作人员,当数据库重新上线时,他们无法正确恢复。
并且 docker/kubernetes 会在应用关闭时通知并自动重启。

问题

我怎样才能达到预期的行为?
可悲的是,我在网上找不到类似的东西。

【问题讨论】:

    标签: java spring hikaricp


    【解决方案1】:

    根据@Zubair 的提示,我构建了一个新的小型解决方案。
    我正在使用Spring-Actuator-package,因为他们为此用例准备了一些类。

    我只需要一个HealthIndicator-Bean,就像这样

    @Bean
    public HealthIndicator dataSourceHealthIndicator(final DataSource dataSource) {
      return new DataSourceHealthIndicator(dataSource, "SELECT 1;");
    }
    

    和预定的观察者(因为 HikariCP 和 HealthIndicators 有任何事件)。

    @Scheduled(fixedRate = 10000L)
    public void checkDBHealth() {
      final Status status = this.dataSourceHealthIndicator.health().getStatus();
      if (!Status.UP.equals(status)) {
        log.error("DATABASE IS OFFLINE! SHUTTING DOWN!");
        System.exit(1);
      }
    }
    

    我希望这对其他人有用。

    编辑

    我不得不更改 HikariCP 的配置。否则,运行状况检查器几乎无休止地等待数据库连接。

    @Bean
    public DataSource dataSource() {
      final HikariConfig config = new HikariConfig();
      // default settings with user, password, jdbc, ...
      config.setInitializationFailTimeout(1000);
      config.setConnectionTimeout(1000);
      config.setValidationTimeout(1000);
    
      return new HikariDataSource(config);
    }
    

    【讨论】:

    • 另外,请提及您使用的执行器的 maven 依赖项...对其他人有帮助。
    【解决方案2】:

    如果是spring 2.0,你可以从一些监控服务调用关闭执行器。

    【讨论】:

    • 嗯。可以使用 bean 作为监控服务吗?
    • 您可以公开一个 Rest-endpoint 并且该功能可以由一个 bean 提供。我认为是的,一个 bean 可以在某些 url / 端点上 ping。
    • 看看你是否从 localhost:8080/actuator/health 检查 app/db 的健康状况,并且可以检查...如果健康状况不佳,请从执行器调用 shudown 端点...我建议查看执行器
    • 没有直接的方法吗?像这样的东西:docs.spring.io/spring-boot/docs/current/api/org/springframework/…
    • 我完成了。感谢您对执行器的建议,这很有帮助。 :)
    【解决方案3】:

    您可以在属性文件中禁用执行器默认提供的健康指标,并通过将其注册为 bean 来替换您的自定义 DatasourceHealthIndicator

    @Bean
    public DataSourceHealthIndicator dataSourceHealthIndicator(){
        return new DataSourceHealthIndicator(dataSource, "SELECT 1");
    }
    
    @Component
    @RequiredArgsConstructor
    public class CustomHealth implements HealthIndicator {
    
        @Override
        public Health health() {
            ...
            return Health.status(healthIndicator.health().getStatus()).build();
        }
    
        private final DataSourceHealthIndicator healthIndicator;
    }
    
    YML
    
    management:
      health:
        db:
          enabled: false
          
    Properties
    
    management.health.db.enabled: false
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-23
      • 1970-01-01
      • 1970-01-01
      • 2017-11-06
      • 2011-04-11
      • 1970-01-01
      相关资源
      最近更新 更多