我们正在使用带有Spring Data for Apache Cassandra的Spring Boot 1.5.10,这一切都运行良好。
我们已经有了新的要求,我们需要在服务启动并运行时连接到不同的密钥空间。
通过使用Spring Cloud Config Server,我们可以轻松设置spring.data.cassandra.keyspace-name
的值,但是,我们不确定是否有办法可以动态切换(强制)服务以使用此新服务密钥空间,如果先没有重新启动?
有任何想法或建议吗?
答案 0 :(得分:1)
是的,你可以在持有spring.data.cassandra.keyspace-name
值的bean上使用@RefreshScope
注释。
通过Spring Cloud Config Server更改配置值后,您必须在应用程序的/refresh
端点上发出POST。
标记为@RefreshScope的Spring @Bean将在配置更改时获得特殊处理。这解决了有状态bean的问题,只有在初始化时才会注入其配置。例如,如果数据源在通过环境更改数据库URL时具有打开的连接,我们可能希望这些连接的持有者能够完成他们正在做的事情。然后,当有人从池中借用连接时,他会获得一个带有新URL的连接。
来自RefreshScope class javadoc:
一种Scope实现,允许在运行时动态刷新bean(请参阅refresh(String)和refreshAll())。如果刷新bean,则在下次访问bean时(即执行方法),将创建一个新实例。所有生命周期方法都应用于bean实例,因此在刷新时会调用在bean工厂中注册的任何销毁回调,然后在创建新实例时正常调用初始化回调。从原始bean定义创建新的bean实例,因此在创建时会重新评估任何外化内容(属性占位符或字符串文字中的表达式)。
答案 1 :(得分:1)
将@RefreshScope
与属性/存储库一起使用不起作用,因为键空间绑定到Cassandra Session
bean。
在Spring Boot 1.5中使用Spring Data Cassandra 1.5,您至少有两个选择:
@RefreshScope
CassandraSessionFactoryBean
,另请参阅CassandraDataAutoConfiguration
。这将在刷新时中断所有Cassandra操作并重新创建所有依赖bean。收听RefreshScopeRefreshedEvent
并通过USE my-new-keyspace;
更改密钥空间。这种方法侵入性较小,不会中断正在运行的查询。你基本上使用了一个事件监听器。
@Component
class MySessionRefresh {
private final Session session;
private final Environment environment;
// omitted constructors for brevity
@EventListener
@Order(Ordered.LOWEST_PRECEDENCE)
public void handle(RefreshScopeRefreshedEvent event) {
String keyspace = environment.getProperty("spring.data.cassandra.keyspace-name");
session.execute("USE " + keyspace + ";");
}
}
使用Spring Data Cassandra 2,我们为代码控制的CQL /会话调用路由引入了SessionFactory
抽象提供AbstractRoutingSessionFactory
。