【问题标题】:Check Session with Cassandra Datastax Java Driver使用 Cassandra Datastax Java 驱动程序检查会话
【发布时间】:2013-09-09 20:27:12
【问题描述】:
是否有任何直接的方法来检查集群/会话是否已连接/有效/正常?
我的意思是,我在一个永无止境的线程中创建了一个 com.datastax.driver.core.Session,我想确保每次需要时会话都正常。我使用下一个集群初始化,但我不确定这是否足够......
Cluster.builder().addContactPoint(url)
.withRetryPolicy(DowngradingConsistencyRetryPolicy.INSTANCE)
.withReconnectionPolicy(new ConstantReconnectionPolicy(1000L)).build());
【问题讨论】:
标签:
session
cassandra
datastax-java-driver
【解决方案1】:
事实上,在使用 DataStax Java 驱动程序时,您嵌入了一个隐藏/神奇的功能:
驱动程序了解完整的网络拓扑(跨数据中心的节点拓扑和节点可用性)。
因此,您唯一需要做的就是使用几个节点 (1) 初始化集群,然后您可以随时确定是否至少有一个可用节点请求将被正确执行。由于驱动程序具有拓扑感知能力,因此如果一个节点(甚至是初始化节点)不可用,驱动程序会自动将您的请求路由到另一个可用节点。
总之,你的代码很好(1)。
(1):您应该提供一些节点,以便在集群初始化阶段具有容错能力。实际上,如果一个初始化节点关闭,驱动程序就有可能联系另一个初始化节点以发现完整的拓扑。
【解决方案2】:
我有一个本地开发环境设置,我正在同时启动我的 java 应用程序和 Cassandra (Docker) 容器,因此当 java 应用程序第一次尝试连接时,Cassandra 通常不会处于就绪状态。
当它启动时,当Cluster 实例尝试创建Session 时,应用程序将抛出NoHostAvailableException。随后尝试从Cluster 创建Session 将引发IllegalStateException,因为集群实例在第一个异常后关闭。
我所做的补救措施是创建一个检查方法,该方法尝试创建一个集群和会话,然后立即关闭它们。看到这个:
private void waitForCassandraToBeReady(String keyspace, Cluster.Builder builder) {
RuntimeException exception = null;
int retries = 0;
while (retries++ < 40) {
Session session = null;
Cluster cluster = null;
try {
cluster = builder.build();
session = cluster.connect(keyspace);
log.info("Cassandra is available");
return;
} catch (RuntimeException e) {
log.warn("Cassandra not available, try {}", retries);
exception = e;
} finally {
if (session != null && !session.isClosed()) session.close();
if (cluster != null && !cluster.isClosed()) cluster.close();
}
sleep();
}
log.error("Retries exceeded waiting for Cassandra to be available");
if (exception != null) throw exception;
else throw new RuntimeException("Cassandra not available");
}
这个方法返回后,我再创建一个独立于这个检查方法的Cluster和Session。