我在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;
}
}
有什么建议吗?
2条答案
按热度按时间pcww981p1#
您可以设置选项
datastax-java-driver.advanced.reconnect-on-init
为了达到你想要的效果。其用法在驱动程序文档的配置参考页中进行了说明:如果在第一次初始化尝试时无法访问所有接触点,是否计划重新连接尝试。如果这是真的,驱动程序将根据重新连接策略重试。这个
SessionBuilder.build()
呼叫-或未来返回SessionBuilder.buildAsync()
-在到达接触点之前无法完成。如果这是错误的,并且没有可用的接触点,则驱动程序将失败,并且AllNodesFailedException
.但是要小心:如上所述,当此选项设置为true时,任何试图访问
CqlSession
即使会话bean是懒惰的,bean也会阻塞,直到驱动程序能够连接,如果接触点错误,它可能会永远阻塞。如果你不能接受的话,我建议你把衣服包起来
CqlSession
另一个bean中的bean,它将检查SessionBuilder.buildAsync()
是否完成,以及阻塞、抛出或返回null,这取决于调用者的期望。sr4lhrrt2#
[编辑]我昨晚已经联系了datastax司机团队,adutra已经回复了,所以我收回了我的回复。