Spring Boot连接Elasticsearch实例化Repository失败,报Connection is closed错误
Spring Boot 3.2.0 连接 Elasticsearch 8.11.1 实例化Repository失败问题解决
问题描述
搭建Spring Boot应用连接Elasticsearch,配置类如下:
@Configuration public class ElasticSearchConfig extends ElasticsearchConfiguration { @Override public ClientConfiguration clientConfiguration() { return ClientConfiguration.builder() .connectedTo("localhost:9200") .build(); } }
使用版本:
- Spring Boot:3.2.0
- Elasticsearch:8.11.1
- Java:21
实例化Elasticsearch Repository时失败,抛出核心异常为ConnectionClosedException的堆栈信息:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository]: Constructor threw exception at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:223) ~[spring-beans-6.1.1.jar:6.1.1] at org.springframework.data.repository.core.support.RepositoryFactorySupport.lambda$instantiateClass$5(RepositoryFactorySupport.java:571) ~[spring-data-commons-3.2.0.jar:3.2.0] at java.base/java.util.Optional.map(Optional.java:260) ~[na:na] at org.springframework.data.repository.core.support.RepositoryFactorySupport.instantiateClass(RepositoryFactorySupport.java:571) ~[spring-data-commons-3.2.0.jar:3.2.0] at org.springframework.data.repository.core.support.RepositoryFactorySupport.getTargetRepositoryViaReflection(RepositoryFactorySupport.java:536) ~[spring-data-commons-3.2.0.jar:3.2.0] at org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactory.getTargetRepository(ElasticsearchRepositoryFactory.java:79) ~[spring-data-elasticsearch-5.2.0.jar:5.2.0] at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:317) ~[spring-data-commons-3.2.0.jar:3.2.0] at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.lambda$afterPropertiesSet$5(RepositoryFactoryBeanSupport.java:279) ~[spring-data-commons-3.2.0.jar:3.2.0] at org.springframework.data.util.Lazy.getNullable(Lazy.java:135) ~[spring-data-commons-3.2.0.jar:3.2.0] at org.springframework.data.util.Lazy.get(Lazy.java:113) ~[spring-data-commons-3.2.0.jar:3.2.0] at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:285) ~[spring-data-commons-3.2.0.jar:3.2.0] at org.springframework.data.elasticsearch.repository.support.ElasticsearchRepositoryFactoryBean.afterPropertiesSet(ElasticsearchRepositoryFactoryBean.java:69) ~[spring-data-elasticsearch-5.2.0.jar:5.2.0] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1822) ~[spring-beans-6.1.1.jar:6.1.1] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1771) ~[spring-beans-6.1.1.jar:6.1.1] ... 44 common frames omitted Caused by: org.springframework.dao.DataAccessResourceFailureException: Connection is closed at org.springframework.data.elasticsearch.client.elc.ElasticsearchExceptionTranslator.translateExceptionIfPossible(ElasticsearchExceptionTranslator.java:110) ~[spring-data-elasticsearch-5.2.0.jar:5.2.0] at org.springframework.data.elasticsearch.client.elc.ElasticsearchExceptionTranslator.translateException(ElasticsearchExceptionTranslator.java:64) ~[spring-data-elasticsearch-5.2.0.jar:5.2.0] at org.springframework.data.elasticsearch.client.elc.ChildTemplate.execute(ChildTemplate.java:73) ~[spring-data-elasticsearch-5.2.0.jar:5.2.0] at org.springframework.data.elasticsearch.client.elc.IndicesTemplate.doExists(IndicesTemplate.java:177) ~[spring-data-elasticsearch-5.2.0.jar:5.2.0] at org.springframework.data.elasticsearch.client.elc.IndicesTemplate.exists(IndicesTemplate.java:169) ~[spring-data-elasticsearch-5.2.0.jar:5.2.0] at org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository.<init>(SimpleElasticsearchRepository.java:85) ~[spring-data-elasticsearch-5.2.0.jar:5.2.0] at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62) ~[na:na] at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502) ~[na:na] at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486) ~[na:na] at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:210) ~[spring-beans-6.1.1.jar:6.1.1] ... 57 common frames omitted Caused by: java.lang.RuntimeException: Connection is closed at org.springframework.data.elasticsearch.client.elc.ElasticsearchExceptionTranslator.translateException(ElasticsearchExceptionTranslator.java:63) ~[spring-data-elasticsearch-5.2.0.jar:5.2.0] ... 65 common frames omitted Caused by: org.apache.http.ConnectionClosedException: Connection is closed at org.elasticsearch.client.RestClient.extractAndWrapCause(RestClient.java:920) ~[elasticsearch-rest-client-8.10.4.jar:8.10.4] at org.elasticsearch.client.RestClient.performRequest(RestClient.java:300) ~[elasticsearch-rest-client-8.10.4.jar:8.10.4] at org.elasticsearch.client.RestClient.performRequest(RestClient.java:288) ~[elasticsearch-rest-client-8.10.4.jar:8.10.4] at co.elastic.clients.transport.rest_client.RestClientHttpClient.performRequest(RestClientHttpClient.java:91) ~[elasticsearch-java-8.10.4.jar:na] at co.elastic.clients.transport.ElasticsearchTransportBase.performRequest(ElasticsearchTransportBase.java:137) ~[elasticsearch-java-8.10.4.jar:na] at co.elastic.clients.elasticsearch.indices.ElasticsearchIndicesClient.exists(ElasticsearchIndicesClient.java:655) ~[elasticsearch-java-8.10.4.jar:na] at org.springframework.data.elasticsearch.client.elc.IndicesTemplate.lambda$doExists$2(IndicesTemplate.java:177) ~[spring-data-elasticsearch-5.2.0.jar:5.2.0] at org.springframework.data.elasticsearch.client.elc.ChildTemplate.execute(ChildTemplate.java:71) ~[spring-data-elasticsearch-5.2.0.jar:5.2.0] ... 64 common frames omitted Caused by: org.apache.http.ConnectionClosedException: Connection is closed at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.endOfInput(HttpAsyncRequestExecutor.java:356) ~[httpcore-nio-4.4.16.jar:4.4.16] at org.apache.http.impl.nio.DefaultNHttpClientConnection.consumeInput(DefaultNHttpClientConnection.java:261) ~[httpcore-nio-4.4.16.jar:4.4.16] at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:87) ~[httpasyncclient-4.1.5.jar:4.1.5] at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:40) ~[httpasyncclient-4.1.5.jar:4.1.5] at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:114) ~[httpcore-nio-4.4.16.jar:4.4.16] at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:162) ~[httpcore-nio-4.4.16.jar:4.4.16] at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:337) ~[httpcore-nio-4.4.16.jar:4.4.16] at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315) ~[httpcore-nio-4.4.16.jar:4.4.16] at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276) ~[httpcore-nio-4.4.16.jar:4.4.16] at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104) ~[httpcore-nio-4.4.16.jar:4.4.16] at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591) ~[httpcore-nio-4.4.16.jar:4.4.16] at java.base/java.lang.Thread.run(Thread.java:1583) ~[na:na]
问题分析
- 版本不兼容:Spring Boot 3.2.0默认集成的Spring Data Elasticsearch 5.2.0依赖的Elasticsearch客户端版本是8.10.4,与你使用的Elasticsearch服务端8.11.1版本不匹配,导致连接协议兼容性问题。
- 未处理安全配置:Elasticsearch 8.x默认开启HTTPS和身份验证,你的配置类未配置SSL信任和账号密码,直接连接会被服务端拒绝,引发连接关闭异常。
解决方案
1. 对齐客户端与服务端版本
在pom.xml中手动指定Elasticsearch版本,确保客户端与服务端版本一致:
<properties> <elasticsearch.version>8.11.1</elasticsearch.version> </properties>
2. 配置SSL与身份验证
修改配置类,添加SSL信任和账号密码验证:
@Configuration public class ElasticSearchConfig extends ElasticsearchConfiguration { @Value("${spring.elasticsearch.uris}") private String uris; @Value("${spring.elasticsearch.username}") private String username; @Value("${spring.elasticsearch.password}") private String password; @Override public ClientConfiguration clientConfiguration() { try { // 开发环境禁用SSL证书验证,生产环境建议配置信任证书 SSLContext sslContext = SSLContextBuilder.create() .loadTrustMaterial((chain, authType) -> true) .build(); return ClientConfiguration.builder() .connectedTo(uris.split(",")) .withBasicAuth(username, password) .withSslContext(sslContext) .build(); } catch (Exception e) { throw new RuntimeException("Failed to create SSL context", e); } } }
在application.properties中添加配置:
spring.elasticsearch.uris=https://localhost:9200 spring.elasticsearch.username=elastic spring.elasticsearch.password=你的Elasticsearch密码
注:Elasticsearch默认密码可在服务启动日志中找到,或使用
elasticsearch-reset-password命令重置。
3. 验证Elasticsearch服务可用性
先通过命令行验证服务是否正常:
curl -u elastic:你的密码 https://localhost:9200 -k
返回服务信息则说明服务正常。
4. 可选:关闭自动索引创建
如果Repository初始化时因索引检查失败导致问题,可在实体类上添加@Document(createIndex = false),手动创建索引后再启动应用。
内容的提问来源于stack exchange,提问作者Ammar Mohamed
相关产品推荐
相关产品推荐

