Spring Cassandra 超时查询'SELECT * FROM system_schema.tables' PT2S 后超时
Spring Cassandra time out query 'SELECT * FROM system_schema.tables' timed out after PT2S
我正在使用 Spring Boot 2.4.4
和 Spring Data Cassandra 依赖项来连接到 Cassandra 数据库。在应用程序启动期间,我收到 DriverTimeout 错误(我正在使用 VPN)。
我已经完成了所有与此类似的 Stack Overflow 问题,其中 none 对我有用。我在 Spring Boot official page here.
上交叉 post 了同样的问题
我在下面使用了以下配置属性 -
spring.data.cassandra.contact-points=xxxxxx
spring.data.cassandra.username=xxxx
spring.data.cassandra.password=xxxxx
spring.data.cassandra.keyspace-name=xxxx
spring.data.cassandra.port=9042
spring.data.cassandra.schema-action=NONE
spring.data.cassandra.local-datacenter=mydc
spring.data.cassandra.connection.connect-timeout=PT10S
spring.data.cassandra.connection.init-query-timeout=PT20S
spring.data.cassandra.request.timeout=PT10S
我还在 application.properties 中添加了 DataStax 属性以检查是否可以从那里获取它们。
datastax-java-driver.basic.request.timeout = 10 seconds
datastax-java-driver.advanced.connection.init-query-timeout = 10 seconds
datastax-java-driver.advanced.control-connection.timeout = 10 seconds
下面是我在 post -
中建议使用的配置
@EnableCassandraRepositories
public class CassandraConfig {
@Bean
DriverConfigLoaderBuilderCustomizer cassandraDriverCustomizer() {
return (builder) -> builder.withDuration(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT,
Duration.ofSeconds(30));
}
}
但我仍然得到同样的错误
Caused by: com.datastax.oss.driver.api.core.DriverTimeoutException: query 'SELECT * FROM system_schema.tables' timed out after PT2S
我还尝试了不同的方法,例如创建自定义 CqlSessionFactoryBean 并以编程方式提供所有 DataStax 属性以覆盖 -
@EnableCassandraRepositories
public class CassandraConfig extends AbstractCassandraConfiguration {
@Bean(name = "session")
@Primary
public CqlSessionFactoryBean cassandraSession() {
CqlSessionFactoryBean factory = new CqlSessionFactoryBean();
factory.setUsername(userName);
factory.setPassword(password);
factory.setPort(port);
factory.setKeyspaceName(keyspaceName);
factory.setContactPoints(contactPoints);
factory.setLocalDatacenter(dataCenter);
factory.setSessionBuilderConfigurer(getSessionBuilderConfigurer()); // my session builder configurer
return factory;
}
// And provided my own SessionBuilder Configurer like below
protected SessionBuilderConfigurer getSessionBuilderConfigurer() {
return new SessionBuilderConfigurer() {
@Override
public CqlSessionBuilder configure(CqlSessionBuilder cqlSessionBuilder) {
ProgrammaticDriverConfigLoaderBuilder config = DriverConfigLoader.programmaticBuilder()
.withDuration(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT, Duration.ofSeconds(30))
.withBoolean(DefaultDriverOption.RECONNECT_ON_INIT, true)
.withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofSeconds(30))
.withDuration(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT, Duration.ofSeconds(20));
return cqlSessionBuilder.withAuthCredentials(userName, password).withConfigLoader(config.build());
}
};
}
}
它没有工作同样的错误。此外,我排除了 Cassandra 自动配置 类,就像 Whosebug
上建议的
我还尝试像下面那样自定义自定义会话构建器,看看是否可行 -
@Bean
public CqlSessionBuilderCustomizer cqlSessionBuilderCustomizer() {
return cqlSessionBuilder -> cqlSessionBuilder.withAuthCredentials(userName, password)
.withConfigLoader(DriverConfigLoader.programmaticBuilder()
.withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofMillis(15000))
.withDuration(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT, Duration.ofSeconds(30))
.withBoolean(DefaultDriverOption.RECONNECT_ON_INIT, true)
.withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofSeconds(30))
.withDuration(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT, Duration.ofSeconds(20)).build());
}
仍然没有运气。
不仅如此,我还添加了 application.conf
文件,因为 DataStax documentation 建议将其放在类路径中,即使该文件正在被解析(在犯了语法错误之后我才知道它正在阅读)。没用。
application.conf-
datastax-java-driver {
basic.request.timeout = 10 seconds
advanced.connection.init-query-timeout = 10 seconds
advanced.control-connection.timeout = 10 seconds
}
我还将我的 Spring 引导版本切换到 2.5.0.M3
以查看 属性 文件是否正常工作。我已将我的项目推送到 my GitHub account.
更新
根据评论,我正在粘贴我的整个堆栈跟踪。此外,这不会一直发生,有时它会起作用,有时它不会。我需要覆盖从 PT2S 到 PT10S 或其他东西的超时。
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraConverter' defined in class path resource [com/example/demo/CassandraConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.cassandra.core.convert.CassandraConverter]: Factory method 'cassandraConverter' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraSession' defined in class path resource [com/example/demo/CassandraConfig.class]: Invocation of init method failed; nested exception is com.datastax.oss.driver.api.core.DriverTimeoutException: query 'SELECT * FROM system_schema.tables' timed out after PT2S
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:484) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=19=](AbstractBeanFactory.java:323) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:895) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at com.example.demo.SpringCassandraTestingApplication.main(SpringCassandraTestingApplication.java:13) [classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.cassandra.core.convert.CassandraConverter]: Factory method 'cassandraConverter' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraSession' defined in class path resource [com/example/demo/CassandraConfig.class]: Invocation of init method failed; nested exception is com.datastax.oss.driver.api.core.DriverTimeoutException: query 'SELECT * FROM system_schema.tables' timed out after PT2S
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
... 19 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraSession' defined in class path resource [com/example/demo/CassandraConfig.class]: Invocation of init method failed; nested exception is com.datastax.oss.driver.api.core.DriverTimeoutException: query 'SELECT * FROM system_schema.tables' timed out after PT2S
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=19=](AbstractBeanFactory.java:323) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:227) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1174) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:422) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:352) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.data.cassandra.config.AbstractSessionConfiguration.requireBeanOfType(AbstractSessionConfiguration.java:100) ~[spring-data-cassandra-3.0.0.RELEASE.jar:3.0.0.RELEASE]
at org.springframework.data.cassandra.config.AbstractSessionConfiguration.getRequiredSession(AbstractSessionConfiguration.java:200) ~[spring-data-cassandra-3.0.0.RELEASE.jar:3.0.0.RELEASE]
at org.springframework.data.cassandra.config.AbstractCassandraConfiguration.cassandraConverter(AbstractCassandraConfiguration.java:73) ~[spring-data-cassandra-3.0.0.RELEASE.jar:3.0.0.RELEASE]
at com.example.demo.CassandraConfig$$EnhancerBySpringCGLIB$$cec229ff.CGLIB$cassandraConverter(<generated>) ~[classes/:na]
at com.example.demo.CassandraConfig$$EnhancerBySpringCGLIB$$cec229ff$$FastClassBySpringCGLIB$$faa9c2c1.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at com.example.demo.CassandraConfig$$EnhancerBySpringCGLIB$$cec229ff.cassandraConverter(<generated>) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_275]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_275]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_275]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_275]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
... 20 common frames omitted
Caused by: com.datastax.oss.driver.api.core.DriverTimeoutException: query 'SELECT * FROM system_schema.tables' timed out after PT2S
at com.datastax.oss.driver.api.core.DriverTimeoutException.copy(DriverTimeoutException.java:34) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures.getUninterruptibly(CompletableFutures.java:149) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.api.core.session.Session.refreshSchema(Session.java:140) ~[java-driver-core-4.6.1.jar:na]
at org.springframework.data.cassandra.config.CqlSessionFactoryBean.afterPropertiesSet(CqlSessionFactoryBean.java:437) ~[spring-data-cassandra-3.0.0.RELEASE.jar:3.0.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1855) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1792) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
... 43 common frames omitted
当驱动程序未从协调器节点获得回复时,将抛出 DriverTimeoutException
。它使用 2 秒的基本请求超时默认值:
datastax-java-driver {
basic.request {
timeout = 2 seconds
超时为 2 秒的事实意味着 none 您的覆盖正在被拾取,但我还没有完全弄清楚原因。
更重要的是,这是与读取或写入超时异常不同的错误,后者是在没有足够的副本响应以满足所需的一致性级别时发生的——在这两种情况中的任何一种情况下,协调器都会将异常回复给驱动程序.
根据我的经验,DriverTimeoutException
是由 (a) 无响应的节点,and/or (b) 过载的协调器引起的。
如果应用 运行 是一个昂贵的查询,这可能是协调器没有及时回复的原因。在这种情况下,您的覆盖不起作用不是您需要解决的问题,因为在 Cassandra 术语中,2 秒是应用程序请求的永恒——您需要确保您没有使集群过载,这就是您需要解决的问题解决。干杯!
所以我在这里看到两种可能性。
- 这个问题最有趣的部分...
...是 SELECT
语句:
SELECT * FROM system_schema.tables
system_schema
的键空间定义是这样的:
CREATE KEYSPACE system_schema WITH replication = {'class': 'LocalStrategy'}
这是更改为简单拓扑还是网络拓扑?如果是这样,那可能会导致超时,特别是。
system_schema
键空间对于较新版本的 Cassandra(我认为是 2.2+)来说是新的。您可能使用的是旧版本吗?
基本上,确保 system_schema
设置了适当的默认复制。此外,请确保使用已知可与您的 Cassandra 版本配合使用的 Spring Data Cassandra 版本。
此外,我建议您在 不使用 Spring Data Cassandra 的情况下尝试这个。我很好奇这与仅使用纯 DS Java 驱动程序之间是否有任何区别。
我在这里回答我自己的问题,使这个问题完整,并让其他人知道我是如何解决这个特定问题的。
我正在使用 Spring Boot 2.4.5。当我升级到 2.3+ 版本时,我开始面临这个超时问题。
根据我对这个问题的经验,以下是我的发现。
无论您在 application.properties
或 application.conf
(DataStax notion) 中提供的任何超时,它们都会以某种方式被 spring 引导覆盖或可能选择默认设置来自 DataStax 驱动程序的值。
甚至在 Spring Boot 官方项目上创建了一个问题来处理这个问题。检查 here。稍后在 2.5.0.M1 版本中得到修复。
当我将其作为 VM 参数传递时,我的问题得到解决。
$java -Ddatastax-java-driver.basic.request.timeout="15 seconds" application.jar
我传递了其他参数以及 advanced.control-connection.timeout
,因为有人建议我在不同的论坛上使用,但这对我不起作用。查看参考手册 here 了解其他配置参数。
我只在本地遇到这个错误,所以我在 Eclipse VM 参数中传递了这个错误,然后我就再也没有看到那个错误了。
此外,如果我将此时间减少到 7-8 秒,有时我会再次看到该错误 PT2S
。似乎无论您传递的超时值如何,该异常消息都被硬编码在某处。 (这是我的观察)。
更新:解决方案 2 - 这是我后来发现的,我看到很多人也回答了这个问题
DataStax 提供的实际密钥在下面给出并且有效。
@Bean
public DriverConfigLoaderBuilderCustomizer defaultProfile(){
return builder -> builder.withString(DefaultDriverOption.METADATA_SCHEMA_REQUEST_TIMEOUT, "3 seconds").build();
}
尝试创建一个 bean,如下所示:
@Bean
public DriverConfigLoaderBuilderCustomizer defaultProfile(){
return builder -> builder.withString(DefaultDriverOption.METADATA_SCHEMA_REQUEST_TIMEOUT, "3 seconds").build();
}
或
@Bean
public DriverConfigLoaderBuilderCustomizer defaultProfile(){
return builder -> builder.withInt(DefaultDriverOption.METADATA_SCHEMA_REQUEST_TIMEOUT, 3000).build();
}
您需要在 session builder 配置器中添加这个:
withDuration(DefaultDriverOption.METADATA_SCHEMA_REQUEST_TIMEOUT, Duration.ofSeconds(XX))
除了提供正确答案的人之外,这里还有一个扩展答案。
增加 METADATA_SCHEMA_REQUEST_TIMEOUT 因为问题中所述的查询属于 METADATA_SCHEMA,这不是明确的。
@Override
protected SessionBuilderConfigurer getSessionBuilderConfigurer() {
return new SessionBuilderConfigurer() {
@Override
public CqlSessionBuilder configure(CqlSessionBuilder cqlSessionBuilder) {
logger.info("Configuring CqlSession Builder");
return cqlSessionBuilder
.withConfigLoader(DriverConfigLoader.programmaticBuilder()
// Resolves the timeout query 'SELECT * FROM system_schema.tables' timed out after PT2S
.withDuration(DefaultDriverOption.METADATA_SCHEMA_REQUEST_TIMEOUT, Duration.ofMillis(60000))
.withDuration(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT, Duration.ofMillis(60000))
.withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofMillis(15000))
.build());
}
};
}
增加请求超时确实解决了问题。
但我们超时的主要原因是“DefaultDriverOption.METADATA_SCHEMA_ENABLED”的默认值为真
通过将值覆盖为 false 将提高速度。
kotlin 示例如下:
class CassandraConfiguration(
private val cassandraProperties: CassandraProperties,
) : AbstractReactiveCassandraConfiguration() {
...
...
override fun getDriverConfigLoaderBuilderConfigurer(): DriverConfigLoaderBuilderConfigurer? {
return DriverConfigLoaderBuilderConfigurer{ builder: ProgrammaticDriverConfigLoaderBuilder ->
builder
.withString(DefaultDriverOption.METADATA_SCHEMA_ENABLED, "false")
.build()
}
}
}
我正在使用 Spring Boot 2.4.4
和 Spring Data Cassandra 依赖项来连接到 Cassandra 数据库。在应用程序启动期间,我收到 DriverTimeout 错误(我正在使用 VPN)。
我已经完成了所有与此类似的 Stack Overflow 问题,其中 none 对我有用。我在 Spring Boot official page here.
上交叉 post 了同样的问题我在下面使用了以下配置属性 -
spring.data.cassandra.contact-points=xxxxxx
spring.data.cassandra.username=xxxx
spring.data.cassandra.password=xxxxx
spring.data.cassandra.keyspace-name=xxxx
spring.data.cassandra.port=9042
spring.data.cassandra.schema-action=NONE
spring.data.cassandra.local-datacenter=mydc
spring.data.cassandra.connection.connect-timeout=PT10S
spring.data.cassandra.connection.init-query-timeout=PT20S
spring.data.cassandra.request.timeout=PT10S
我还在 application.properties 中添加了 DataStax 属性以检查是否可以从那里获取它们。
datastax-java-driver.basic.request.timeout = 10 seconds
datastax-java-driver.advanced.connection.init-query-timeout = 10 seconds
datastax-java-driver.advanced.control-connection.timeout = 10 seconds
下面是我在 post
@EnableCassandraRepositories
public class CassandraConfig {
@Bean
DriverConfigLoaderBuilderCustomizer cassandraDriverCustomizer() {
return (builder) -> builder.withDuration(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT,
Duration.ofSeconds(30));
}
}
但我仍然得到同样的错误
Caused by: com.datastax.oss.driver.api.core.DriverTimeoutException: query 'SELECT * FROM system_schema.tables' timed out after PT2S
我还尝试了不同的方法,例如创建自定义 CqlSessionFactoryBean 并以编程方式提供所有 DataStax 属性以覆盖 -
@EnableCassandraRepositories
public class CassandraConfig extends AbstractCassandraConfiguration {
@Bean(name = "session")
@Primary
public CqlSessionFactoryBean cassandraSession() {
CqlSessionFactoryBean factory = new CqlSessionFactoryBean();
factory.setUsername(userName);
factory.setPassword(password);
factory.setPort(port);
factory.setKeyspaceName(keyspaceName);
factory.setContactPoints(contactPoints);
factory.setLocalDatacenter(dataCenter);
factory.setSessionBuilderConfigurer(getSessionBuilderConfigurer()); // my session builder configurer
return factory;
}
// And provided my own SessionBuilder Configurer like below
protected SessionBuilderConfigurer getSessionBuilderConfigurer() {
return new SessionBuilderConfigurer() {
@Override
public CqlSessionBuilder configure(CqlSessionBuilder cqlSessionBuilder) {
ProgrammaticDriverConfigLoaderBuilder config = DriverConfigLoader.programmaticBuilder()
.withDuration(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT, Duration.ofSeconds(30))
.withBoolean(DefaultDriverOption.RECONNECT_ON_INIT, true)
.withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofSeconds(30))
.withDuration(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT, Duration.ofSeconds(20));
return cqlSessionBuilder.withAuthCredentials(userName, password).withConfigLoader(config.build());
}
};
}
}
它没有工作同样的错误。此外,我排除了 Cassandra 自动配置 类,就像 Whosebug
上建议的我还尝试像下面那样自定义自定义会话构建器,看看是否可行 -
@Bean
public CqlSessionBuilderCustomizer cqlSessionBuilderCustomizer() {
return cqlSessionBuilder -> cqlSessionBuilder.withAuthCredentials(userName, password)
.withConfigLoader(DriverConfigLoader.programmaticBuilder()
.withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofMillis(15000))
.withDuration(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT, Duration.ofSeconds(30))
.withBoolean(DefaultDriverOption.RECONNECT_ON_INIT, true)
.withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofSeconds(30))
.withDuration(DefaultDriverOption.CONTROL_CONNECTION_TIMEOUT, Duration.ofSeconds(20)).build());
}
仍然没有运气。
不仅如此,我还添加了 application.conf
文件,因为 DataStax documentation 建议将其放在类路径中,即使该文件正在被解析(在犯了语法错误之后我才知道它正在阅读)。没用。
application.conf-
datastax-java-driver {
basic.request.timeout = 10 seconds
advanced.connection.init-query-timeout = 10 seconds
advanced.control-connection.timeout = 10 seconds
}
我还将我的 Spring 引导版本切换到 2.5.0.M3
以查看 属性 文件是否正常工作。我已将我的项目推送到 my GitHub account.
更新
根据评论,我正在粘贴我的整个堆栈跟踪。此外,这不会一直发生,有时它会起作用,有时它不会。我需要覆盖从 PT2S 到 PT10S 或其他东西的超时。
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraConverter' defined in class path resource [com/example/demo/CassandraConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.cassandra.core.convert.CassandraConverter]: Factory method 'cassandraConverter' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraSession' defined in class path resource [com/example/demo/CassandraConfig.class]: Invocation of init method failed; nested exception is com.datastax.oss.driver.api.core.DriverTimeoutException: query 'SELECT * FROM system_schema.tables' timed out after PT2S
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:484) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=19=](AbstractBeanFactory.java:323) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:895) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) [spring-boot-2.3.0.RELEASE.jar:2.3.0.RELEASE]
at com.example.demo.SpringCassandraTestingApplication.main(SpringCassandraTestingApplication.java:13) [classes/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.cassandra.core.convert.CassandraConverter]: Factory method 'cassandraConverter' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraSession' defined in class path resource [com/example/demo/CassandraConfig.class]: Invocation of init method failed; nested exception is com.datastax.oss.driver.api.core.DriverTimeoutException: query 'SELECT * FROM system_schema.tables' timed out after PT2S
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
... 19 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraSession' defined in class path resource [com/example/demo/CassandraConfig.class]: Invocation of init method failed; nested exception is com.datastax.oss.driver.api.core.DriverTimeoutException: query 'SELECT * FROM system_schema.tables' timed out after PT2S
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean[=19=](AbstractBeanFactory.java:323) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:227) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1174) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:422) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:352) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:345) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.data.cassandra.config.AbstractSessionConfiguration.requireBeanOfType(AbstractSessionConfiguration.java:100) ~[spring-data-cassandra-3.0.0.RELEASE.jar:3.0.0.RELEASE]
at org.springframework.data.cassandra.config.AbstractSessionConfiguration.getRequiredSession(AbstractSessionConfiguration.java:200) ~[spring-data-cassandra-3.0.0.RELEASE.jar:3.0.0.RELEASE]
at org.springframework.data.cassandra.config.AbstractCassandraConfiguration.cassandraConverter(AbstractCassandraConfiguration.java:73) ~[spring-data-cassandra-3.0.0.RELEASE.jar:3.0.0.RELEASE]
at com.example.demo.CassandraConfig$$EnhancerBySpringCGLIB$$cec229ff.CGLIB$cassandraConverter(<generated>) ~[classes/:na]
at com.example.demo.CassandraConfig$$EnhancerBySpringCGLIB$$cec229ff$$FastClassBySpringCGLIB$$faa9c2c1.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at com.example.demo.CassandraConfig$$EnhancerBySpringCGLIB$$cec229ff.cassandraConverter(<generated>) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_275]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_275]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_275]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_275]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
... 20 common frames omitted
Caused by: com.datastax.oss.driver.api.core.DriverTimeoutException: query 'SELECT * FROM system_schema.tables' timed out after PT2S
at com.datastax.oss.driver.api.core.DriverTimeoutException.copy(DriverTimeoutException.java:34) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.internal.core.util.concurrent.CompletableFutures.getUninterruptibly(CompletableFutures.java:149) ~[java-driver-core-4.6.1.jar:na]
at com.datastax.oss.driver.api.core.session.Session.refreshSchema(Session.java:140) ~[java-driver-core-4.6.1.jar:na]
at org.springframework.data.cassandra.config.CqlSessionFactoryBean.afterPropertiesSet(CqlSessionFactoryBean.java:437) ~[spring-data-cassandra-3.0.0.RELEASE.jar:3.0.0.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1855) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1792) ~[spring-beans-5.2.6.RELEASE.jar:5.2.6.RELEASE]
... 43 common frames omitted
当驱动程序未从协调器节点获得回复时,将抛出 DriverTimeoutException
。它使用 2 秒的基本请求超时默认值:
datastax-java-driver {
basic.request {
timeout = 2 seconds
超时为 2 秒的事实意味着 none 您的覆盖正在被拾取,但我还没有完全弄清楚原因。
更重要的是,这是与读取或写入超时异常不同的错误,后者是在没有足够的副本响应以满足所需的一致性级别时发生的——在这两种情况中的任何一种情况下,协调器都会将异常回复给驱动程序.
根据我的经验,DriverTimeoutException
是由 (a) 无响应的节点,and/or (b) 过载的协调器引起的。
如果应用 运行 是一个昂贵的查询,这可能是协调器没有及时回复的原因。在这种情况下,您的覆盖不起作用不是您需要解决的问题,因为在 Cassandra 术语中,2 秒是应用程序请求的永恒——您需要确保您没有使集群过载,这就是您需要解决的问题解决。干杯!
所以我在这里看到两种可能性。
- 这个问题最有趣的部分...
...是 SELECT
语句:
SELECT * FROM system_schema.tables
system_schema
的键空间定义是这样的:
CREATE KEYSPACE system_schema WITH replication = {'class': 'LocalStrategy'}
这是更改为简单拓扑还是网络拓扑?如果是这样,那可能会导致超时,特别是。
system_schema
键空间对于较新版本的 Cassandra(我认为是 2.2+)来说是新的。您可能使用的是旧版本吗?
基本上,确保 system_schema
设置了适当的默认复制。此外,请确保使用已知可与您的 Cassandra 版本配合使用的 Spring Data Cassandra 版本。
此外,我建议您在 不使用 Spring Data Cassandra 的情况下尝试这个。我很好奇这与仅使用纯 DS Java 驱动程序之间是否有任何区别。
我在这里回答我自己的问题,使这个问题完整,并让其他人知道我是如何解决这个特定问题的。
我正在使用 Spring Boot 2.4.5。当我升级到 2.3+ 版本时,我开始面临这个超时问题。
根据我对这个问题的经验,以下是我的发现。
无论您在 application.properties
或 application.conf
(DataStax notion) 中提供的任何超时,它们都会以某种方式被 spring 引导覆盖或可能选择默认设置来自 DataStax 驱动程序的值。
甚至在 Spring Boot 官方项目上创建了一个问题来处理这个问题。检查 here。稍后在 2.5.0.M1 版本中得到修复。
当我将其作为 VM 参数传递时,我的问题得到解决。
$java -Ddatastax-java-driver.basic.request.timeout="15 seconds" application.jar
我传递了其他参数以及 advanced.control-connection.timeout
,因为有人建议我在不同的论坛上使用,但这对我不起作用。查看参考手册 here 了解其他配置参数。
我只在本地遇到这个错误,所以我在 Eclipse VM 参数中传递了这个错误,然后我就再也没有看到那个错误了。
此外,如果我将此时间减少到 7-8 秒,有时我会再次看到该错误 PT2S
。似乎无论您传递的超时值如何,该异常消息都被硬编码在某处。 (这是我的观察)。
更新:解决方案 2 - 这是我后来发现的,我看到很多人也回答了这个问题
DataStax 提供的实际密钥在下面给出并且有效。
@Bean
public DriverConfigLoaderBuilderCustomizer defaultProfile(){
return builder -> builder.withString(DefaultDriverOption.METADATA_SCHEMA_REQUEST_TIMEOUT, "3 seconds").build();
}
尝试创建一个 bean,如下所示:
@Bean
public DriverConfigLoaderBuilderCustomizer defaultProfile(){
return builder -> builder.withString(DefaultDriverOption.METADATA_SCHEMA_REQUEST_TIMEOUT, "3 seconds").build();
}
或
@Bean
public DriverConfigLoaderBuilderCustomizer defaultProfile(){
return builder -> builder.withInt(DefaultDriverOption.METADATA_SCHEMA_REQUEST_TIMEOUT, 3000).build();
}
您需要在 session builder 配置器中添加这个:
withDuration(DefaultDriverOption.METADATA_SCHEMA_REQUEST_TIMEOUT, Duration.ofSeconds(XX))
除了提供正确答案的人之外,这里还有一个扩展答案。
增加 METADATA_SCHEMA_REQUEST_TIMEOUT 因为问题中所述的查询属于 METADATA_SCHEMA,这不是明确的。
@Override
protected SessionBuilderConfigurer getSessionBuilderConfigurer() {
return new SessionBuilderConfigurer() {
@Override
public CqlSessionBuilder configure(CqlSessionBuilder cqlSessionBuilder) {
logger.info("Configuring CqlSession Builder");
return cqlSessionBuilder
.withConfigLoader(DriverConfigLoader.programmaticBuilder()
// Resolves the timeout query 'SELECT * FROM system_schema.tables' timed out after PT2S
.withDuration(DefaultDriverOption.METADATA_SCHEMA_REQUEST_TIMEOUT, Duration.ofMillis(60000))
.withDuration(DefaultDriverOption.CONNECTION_INIT_QUERY_TIMEOUT, Duration.ofMillis(60000))
.withDuration(DefaultDriverOption.REQUEST_TIMEOUT, Duration.ofMillis(15000))
.build());
}
};
}
增加请求超时确实解决了问题。
但我们超时的主要原因是“DefaultDriverOption.METADATA_SCHEMA_ENABLED”的默认值为真
通过将值覆盖为 false 将提高速度。
kotlin 示例如下:
class CassandraConfiguration(
private val cassandraProperties: CassandraProperties,
) : AbstractReactiveCassandraConfiguration() {
...
...
override fun getDriverConfigLoaderBuilderConfigurer(): DriverConfigLoaderBuilderConfigurer? {
return DriverConfigLoaderBuilderConfigurer{ builder: ProgrammaticDriverConfigLoaderBuilder ->
builder
.withString(DefaultDriverOption.METADATA_SCHEMA_ENABLED, "false")
.build()
}
}
}