数据库丢失时关闭 Spring
Shutown Spring when DB is lost
用例
我们的 spring-boot-backend (v 2.3.1) 使用带有 HikariCP 作为连接池的 postgres 数据库。
应用程序在线,管理员不小心杀死了数据库。
预期行为
Spring 注意与数据库的连接丢失了。应用程序将正常关闭。
实际行为
Spring 仍然是 运行。所有需要数据库的方法都以异常结束。
要恢复完整的良好状态,我们需要手动重启spring。
备注
我们有很多异步工作者,当数据库重新联机时,它们无法正确恢复。
并且 docker/kubernetes 会在应用程序关闭时通知并自动重启它。
问题
我怎样才能达到预期的行为?
遗憾的是我在网上找不到类似的东西。
如果是 spring 2.0,您可以从一些监控服务中调用 shut-down 执行器。
根据@Zubair 的提示,我构建了一个新的小解决方案。
我正在使用 Spring-Actuator-package,因为他们为此 use-case.
准备了一些 类
我只需要一个 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 的配置。否则 health-checker 几乎没完没了地等待 database-connection。
@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);
}
您可以在 属性 文件中禁用执行器默认提供的健康指标,并通过将其注册为 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
用例
我们的 spring-boot-backend (v 2.3.1) 使用带有 HikariCP 作为连接池的 postgres 数据库。
应用程序在线,管理员不小心杀死了数据库。
预期行为
Spring 注意与数据库的连接丢失了。应用程序将正常关闭。
实际行为
Spring 仍然是 运行。所有需要数据库的方法都以异常结束。
要恢复完整的良好状态,我们需要手动重启spring。
备注
我们有很多异步工作者,当数据库重新联机时,它们无法正确恢复。
并且 docker/kubernetes 会在应用程序关闭时通知并自动重启它。
问题
我怎样才能达到预期的行为?
遗憾的是我在网上找不到类似的东西。
如果是 spring 2.0,您可以从一些监控服务中调用 shut-down 执行器。
根据@Zubair 的提示,我构建了一个新的小解决方案。
我正在使用 Spring-Actuator-package,因为他们为此 use-case.
我只需要一个 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 的配置。否则 health-checker 几乎没完没了地等待 database-connection。
@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);
}
您可以在 属性 文件中禁用执行器默认提供的健康指标,并通过将其注册为 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