Spring Boot集成多Keyspace响应式Cassandra时如何在Cassandra宕机时正常启动
解决方案
核心原理
Spring Data Cassandra默认会在应用启动阶段同步初始化CqlSession并尝试连接Cassandra集群,连接失败会直接抛出异常终止上下文初始化。只要把连接初始化逻辑从启动阶段移到首次业务调用阶段,即可实现Cassandra宕机时应用也能正常启动。
具体实现步骤
- 第一步:配置CqlSession异步初始化,关闭启动强制连接校验
修改基础配置类中的会话工厂配置,开启异步初始化,同时自定义Datastax驱动参数,允许启动时不强制建立连接:
@Bean @NonNull @Override public CqlSessionFactoryBean cassandraSession() { final CqlSessionFactoryBean cqlSessionFactoryBean = new CqlSessionFactoryBean(); cqlSessionFactoryBean.setContactPoints(contactPoints); cqlSessionFactoryBean.setLocalDatacenter(localDataCenter); cqlSessionFactoryBean.setUsername(username); cqlSessionFactoryBean.setPassword(password); // 开启异步初始化,启动阶段不阻塞等待连接成功 cqlSessionFactoryBean.setAsyncInit(true); // 自定义驱动配置,关闭启动强制连接校验,配置重试策略 DriverConfigLoader loader = DriverConfigLoader.programmaticBuilder() .withBoolean(DefaultDriverOption.RECONNECT_ON_INIT, true) .withDuration(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT, Duration.ofSeconds(2)) .withInt(DefaultDriverOption.CONNECTION_MAX_RETRIES, 3) .build(); cqlSessionFactoryBean.setDriverConfigLoader(loader); return cqlSessionFactoryBean; }
- 第二步:为所有Cassandra相关Bean添加懒加载注解
给Keyspace配置类中的会话、操作模板Bean添加@Lazy注解,启动阶段不会初始化这些Bean,只有首次调用时才会触发实例化和连接逻辑:
@Configuration @EnableReactiveCassandraRepositories(basePackages = "com.abc.repository.cassandra.xyz", reactiveCassandraTemplateRef = "keyspaceXYZTemplate") public class XYZCassandraConfiguration extends CassandraConfig { @Override protected String getKeyspaceName() { return "KEYSPACE_NAME"; } @Bean("keyspaceXYZTemplate") @Lazy // 启动时不初始化,首次调用才实例化 public ReactiveCassandraTemplate reactiveCassandraTemplate(@Qualifier("xyzBean") CqlSessionFactoryBean cqlSessionFactoryBean) { final ReactiveSession reactiveSession = new DefaultBridgedReactiveSession(cqlSessionFactoryBean.getObject()); return new ReactiveCassandraTemplate(reactiveSession, cassandraConverter()); } @NonNull @Override @Primary @Bean(name = "xyzBean") @Lazy // 启动时不初始化会话 public CqlSessionFactoryBean cassandraSession() { final CqlSessionFactoryBean cqlSessionFactoryBean = super.cassandraSession(); cqlSessionFactoryBean.setKeyspaceName(getKeyspaceName()); return cqlSessionFactoryBean; } }
同时所有注入Cassandra Repository的位置也要添加@Lazy注解,避免启动时触发Repository初始化:
@Service public class XyzService { @Lazy @Autowired private XyzRepository xyzRepository; }
- 第三步(可选):添加熔断降级逻辑
可以通过Resilience4j、Sentinel等组件为所有Cassandra操作添加熔断策略,当Cassandra不可用时直接返回降级结果,避免业务调用时报错。
注意事项
如果你的应用启动流程中就有强制调用Cassandra的逻辑,需要同步改造这部分逻辑为降级兼容模式,否则即使加了懒加载,启动时调用还是会触发连接失败异常。
内容的提问来源于stack exchange,提问作者Dhaval
相关产品推荐
相关产品推荐

