带cassandra的spring引导和spring数据:在数据库连接失败时继续

mkshixfv  于 2021-06-13  发布在  Cassandra
关注(0)|答案(2)|浏览(554)

我在cassandra中使用spring boot和spring数据。在应用程序启动时,spring建立到数据库的连接,以设置模式并初始化spring数据存储库。如果数据库不可用,应用程序将无法启动。
我想,应用程序只是记录一个错误并启动。当然,我不能再使用存储库了,但是其他独立于数据库的服务(rest控制器等)应该可以工作。这也将是很高兴看到在健康检查,Cassandra是下来。
对于jdbc,有一个 spring.datasource.continue-on-error 财产。我找不到与Cassandra相似的东西。
我还尝试创建一个定制的cassandra配置,并尝试在cqlsession创建时捕获异常,但无法实现所需的行为。
编辑:根据@adutra的建议,我尝试设置advanced.reconnect-on-init,应用程序尝试建立连接,但应用程序没有完全初始化(例如,rest controller不可访问)

@Configuration
public class CustomCassandraConfiguration extends CassandraAutoConfiguration {
    @Bean
    public DriverConfigLoaderBuilderCustomizer driverConfigLoaderBuilderCustomizer() {
        return builder -> builder.withBoolean(DefaultDriverOption.RECONNECT_ON_INIT, true);
    }
}

edit2:我现在有一个工作示例(应用程序启动,cassandra的自定义健康检查),但是如果感觉很难看:
CustomCassandra自动配置

@Configuration
public class CustomCassandraAutoConfiguration extends CassandraAutoConfiguration {
private final Logger logger = LoggerFactory.getLogger(getClass());

@Override
@Bean
public CqlSession cassandraSession(CqlSessionBuilder cqlSessionBuilder) {
    try {
        return super.cassandraSession(cqlSessionBuilder);
    } catch (AllNodesFailedException e) {
        logger.error("Failed to establish the database connection", e);
    }
    return new DatabaseNotConnectedFakeCqlSession();
}

@Bean
public CassandraReactiveHealthIndicator cassandraHealthIndicator(ReactiveCassandraOperations r, CqlSession session) {
    if (session instanceof DatabaseNotConnectedFakeCqlSession) {
        return new CassandraReactiveHealthIndicator(r) {
            @Override
            protected Mono<Health> doHealthCheck(Health.Builder builder) {
                return Mono.just(builder.down().withDetail("connection", "was not available on startup").build());
            }
        };
    }
    return new CassandraReactiveHealthIndicator(r);
}
}

CustomCassandRadata自动配置

@Configuration
public class CustomCassandraDataAutoConfiguration extends CassandraDataAutoConfiguration {

public CustomCassandraDataAutoConfiguration(CqlSession session) {
    super(session);
}

@Bean
public SessionFactoryFactoryBean cassandraSessionFactory(CqlSession session, Environment environment, CassandraConverter converter) {
    SessionFactoryFactoryBean sessionFactoryFactoryBean = super.cassandraSessionFactory(environment, converter);

    // Disable schema action if database is not available
    if (session instanceof DatabaseNotConnectedFakeCqlSession) {
        sessionFactoryFactoryBean.setSchemaAction(SchemaAction.NONE);
    }
    return sessionFactoryFactoryBean;
}
}

databasenotconnectedfakecqlsession(假会话实现)

public class DatabaseNotConnectedFakeCqlSession implements CqlSession {

@Override
public String getName() {
    return null;
}

@Override
public Metadata getMetadata() {
    return null;
}

@Override
public boolean isSchemaMetadataEnabled() {
    return false;
}

@Override
public CompletionStage<Metadata> setSchemaMetadataEnabled( Boolean newValue) {
    return null;
}

@Override
public CompletionStage<Metadata> refreshSchemaAsync() {
    return null;
}

@Override
public CompletionStage<Boolean> checkSchemaAgreementAsync() {
    return null;
}

@Override
public DriverContext getContext() {
    return new DefaultDriverContext(new DefaultDriverConfigLoader(), ProgrammaticArguments.builder().build());
}

@Override
public Optional<CqlIdentifier> getKeyspace() {
    return Optional.empty();
}

@Override
public Optional<Metrics> getMetrics() {
    return Optional.empty();
}

@Override
public <RequestT extends Request, ResultT> ResultT execute( RequestT request, GenericType<ResultT> resultType) {
    return null;
}

@Override
public CompletionStage<Void> closeFuture() {
    return null;
}

@Override
public CompletionStage<Void> closeAsync() {
    return null;
}

@Override
public CompletionStage<Void> forceCloseAsync() {
    return null;
}

@Override
public Metadata refreshSchema() {
    return null;
}
}

有什么建议吗?

pcww981p

pcww981p1#

您可以设置选项 datastax-java-driver.advanced.reconnect-on-init 为了达到你想要的效果。其用法在驱动程序文档的配置参考页中进行了说明:
如果在第一次初始化尝试时无法访问所有接触点,是否计划重新连接尝试。如果这是真的,驱动程序将根据重新连接策略重试。这个 SessionBuilder.build() 呼叫-或未来返回 SessionBuilder.buildAsync() -在到达接触点之前无法完成。如果这是错误的,并且没有可用的接触点,则驱动程序将失败,并且 AllNodesFailedException .
但是要小心:如上所述,当此选项设置为true时,任何试图访问 CqlSession 即使会话bean是懒惰的,bean也会阻塞,直到驱动程序能够连接,如果接触点错误,它可能会永远阻塞。
如果你不能接受的话,我建议你把衣服包起来 CqlSession 另一个bean中的bean,它将检查 SessionBuilder.buildAsync() 是否完成,以及阻塞、抛出或返回null,这取决于调用者的期望。

sr4lhrrt

sr4lhrrt2#

[编辑]我昨晚已经联系了datastax司机团队,adutra已经回复了,所以我收回了我的回复。

相关问题