我刚刚使用jdk 19升级到Sping Boot 2.7,并决定使用在docker中运行的Cassandra bitnami 3进行测试“Junit-5”,我得到的错误是No node was available to execute the query
,而且每次都发生在相同的测试用例中。
No node was available to execute the query; nested exception is \
com.datastax.oss.driver.api.core.NoNodeAvailableException: \
No node was available to execute the query
这是我用来连接的代码
var loader = DriverConfigLoader.programmaticBuilder()
.withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofMinutes(1))
.withString(DefaultDriverOption.LOAD_BALANCING_POLICY_CLASS,
DcInferringLoadBalancingPolicy.class.getName())
.build();
if (session == null || session.isClosed()) {
var host = System.getenv("CASSANDRA_HOST") == null ? "localhost" : System.getenv("CASSANDRA_HOST");
var username = "localhost".equals(host)? "": "cassandra";
var password = "localhost".equals(host)? "": "cassandra";
LOG.info("Cassandra host '{}'.", host);
LOG.info("Cassandra username '{}'.", username);
LOG.info("Cassandra password '{}'.", password);
var sessionBuilder = new CqlSessionBuilder()
.addContactPoint(new InetSocketAddress(host, 9042))
.withLocalDatacenter("datacenter1")
.withConfigLoader(loader);
if (!username.isEmpty()) {
sessionBuilder.withAuthCredentials(username, password);
}
session = sessionBuilder.build();
同样重要的是要提到,我有很多170多个测试用例分布在不同的文件中,并且在每次执行文件时,我都尝试使用此代码再次清理和填充DB
session.execute("create keyspace if not exists \"schema_x\" WITH replication = {'class':'SimpleStrategy', 'replication_factor' : 1};");
for (final String stmt : getCassaandraStatementsFromFile(CASSANDRA_SCHEMA_FILE)) {
session.execute(stmt);
LOG.info("Cassandra. Executed statement: '{}'.", stmt.replaceAll("\n", ""));
}
并且错误恰好发生在创建keyspace行上,我尝试从我这边进行一些调整
- 调整连接加载器并使用节流,但没有任何帮助
- 我还检查了docker本身内部的本地数据中心值,并与我的值相匹配。
最后,完整的错误堆栈跟踪(如果需要)
org.springframework.data.cassandra.CassandraConnectionFailureException: \
Query; CQL [com.datastax.oss.driver.internal.core.cql.DefaultSimpleStatement@65b70f9e]; \
No node was available to execute the query; nested exception is \
com.datastax.oss.driver.api.core.NoNodeAvailableException: \
No node was available to execute the query
at org.springframework.data.cassandra.core.cql.CassandraExceptionTranslator.translate(CassandraExceptionTranslator.java:137)
at org.springframework.data.cassandra.core.cql.CassandraAccessor.translate(CassandraAccessor.java:422)
at org.springframework.data.cassandra.core.cql.CqlTemplate.translateException(CqlTemplate.java:764)
at org.springframework.data.cassandra.core.cql.CqlTemplate.query(CqlTemplate.java:300)
at org.springframework.data.cassandra.core.cql.CqlTemplate.query(CqlTemplate.java:320)
at org.springframework.data.cassandra.core.CassandraTemplate.select(CassandraTemplate.java:337)
at org.springframework.data.cassandra.repository.query.CassandraQueryExecution$CollectionExecution.execute(CassandraQueryExecution.java:136)
at
...
Caused by: com.datastax.oss.driver.api.core.NoNodeAvailableException: \
No node was available to execute the query
at com.datastax.oss.driver.api.core.NoNodeAvailableException.copy(NoNodeAvailableException.java:40)
at com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures.getUninterruptibly(CompletableFutures.java:149)
at com.datastax.oss.driver.internal.core.cql.CqlRequestSyncProcessor.process(CqlRequestSyncProcessor.java:53)
at com.datastax.oss.driver.internal.core.cql.CqlRequestSyncProcessor.process(CqlRequestSyncProcessor.java:30)
at com.datastax.oss.driver.internal.core.session.DefaultSession.execute(DefaultSession.java:230)
at com.datastax.oss.driver.api.core.cql.SyncCqlSession.execute(SyncCqlSession.java:54)
at org.springframework.data.cassandra.core.cql.CqlTemplate.query(CqlTemplate.java:298)
... 39 common frames omitted
我将感谢您对此的支持,并提前表示感谢
1条答案
按热度按时间wbgh16ku1#
Spring使用Cassandra Java driver连接到Cassandra集群。
对于每个查询执行,Java驱动程序生成查询计划,其中包含要连接以执行查询的节点列表。配置的负载平衡策略(在您的情况下为
DcInferringLoadBalancingPolicy
)确定要包含在查询计划中的节点。查询计划将仅包含已知可用的节点,这意味着策略将不包含已知关闭或忽略的节点(有关详细信息,请参见Load balancing with the Java driver)。在所有节点都被标记为“down”或“ignored”的情况下,驱动程序没有选择,因为没有节点可供连接到the driver throws
NoNodeAvailableException
。正如您在上面发布的错误消息所指出的,* 确实 * 没有节点available to execute the query
--正如它所说的那样。驱动程序将节点标记为“down”或“ignored”,因为它们在一段时间内没有响应,通常是因为它们过载。请考虑进一步限制负载,以便节点不会过载。
此外,架构更改不遵循与常规写入(
INSERT
、UPDATE
、DELETE
)相同的路径。每个DDL更改(CREATE
、ALTER
、DROP
)都通过gossip协议传播到其他节点,因此群集中的所有节点可能需要一些时间才能达成架构协议,具体取决于群集的大小。以编程方式执行架构更改时,不要快速连续地执行更改,否则节点可能会失去同步。应用程序应在每次架构更改后暂停,并在执行下一个架构更改之前检查所有节点是否已达成架构协议,例如,调用
isSchemaInAgreement()
或与checkSchemaAgreementAsync()
异步。有关详细信息,请参阅与Java驱动程序的架构协议。顺便说一句,默认的
cassandra
超级用户不是为一般用途而设计的,它只应该用于配置另一个超级用户帐户,然后将其删除。使用默认的
cassandra
超级用户帐户是昂贵的,因为它需要QUORUM
个节点来进行身份验证。相比之下,除cassandra
之外的所有其他帐户都以ONE
的一致性进行身份验证。干杯!👉 请将鼠标悬停在cassandra标签上,然后单击
Watch tag
按钮,以支持Apache Cassandra社区。🙏谢谢!