java - ES Rest High Level Client 空闲一段时间后抛出 SocketTimeoutException
问题描述
RestHighLevelClient
用于在 spring-boot 应用程序中连接到 ES 6.4(托管在 AWS 上)。当应用程序空闲一段时间,请求到达时,RestHighLevelClient
抛出SocketTimeoutException
:
[Request processing failed; nested exception is org.springframework.data.elasticsearch.ElasticsearchException: Error while bulk for request: org.elasticsearch.action.bulk.BulkRequest@21511b6c] w
java.net.SocketTimeoutException: 5,000 milliseconds timeout on connection http-outgoing-38 [ACTIVE]
at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.timeout(HttpAsyncRequestExecutor.java:387) ~[httpcore-nio-4.4.11.jar!/:4.4.11]
at org.apache.http.impl.nio.client.InternalIODispatch.onTimeout(InternalIODispatch.java:92) ~[httpasyncclient-4.1.4.jar!/:4.1.4]
at org.apache.http.impl.nio.client.InternalIODispatch.onTimeout(InternalIODispatch.java:39) ~[httpasyncclient-4.1.4.jar!/:4.1.4]
at org.apache.http.impl.nio.reactor.AbstractIODispatch.timeout(AbstractIODispatch.java:175) ~[httpcore-nio-4.4.11.jar!/:4.4.11]
at org.apache.http.impl.nio.reactor.BaseIOReactor.sessionTimedOut(BaseIOReactor.java:263) ~[httpcore-nio-4.4.11.jar!/:4.4.11]
at org.apache.http.impl.nio.reactor.AbstractIOReactor.timeoutCheck(AbstractIOReactor.java:492) ~[httpcore-nio-4.4.11.jar!/:4.4.11]
at org.apache.http.impl.nio.reactor.BaseIOReactor.validate(BaseIOReactor.java:213) ~[httpcore-nio-4.4.11.jar!/:4.4.11]
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:280) ~[httpcore-nio-4.4.11.jar!/:4.4.11]
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104) ~[httpcore-nio-4.4.11.jar!/:4.4.11]
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591) ~[httpcore-nio-4.4.11.jar!/:4.4.11]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]
RestHighLevelClient 是使用以下方法创建的:
@Bean
RestHighLevelClient client() {
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
.connectedTo(elasticsearchHostAndPort)
.build();
return RestClients.create(clientConfiguration).rest();
}
spring-data-elasticsearch
使用版本3.2.0.M2
。
任何提示/解决方法?
解决方案
我还尝试按照此处和其他地方的建议将连接/套接字超时设置为 0。它最终没有帮助。
还有另一种解决方案/解决方法,由 https://jira.spring.io/browse/DATAES-789中的 spring-data-elasticsearch 建议。它只是在发生此类异常时执行内部重试。它并不能真正解决问题,但您的客户不会出错。相反,空闲时间后的第一个请求将需要额外的 5 秒(或您配置的任何超时)。
如果您使用 Springboot-data-elasticsearch 版本 4+(以 Springboot 2.3.0 开始),那么您可以应用该解决方案。
我可以确认以下解决方案有效(具有我上面提到的限制):
@Configuration
public class ElasticSearchRestClientConfig extends AbstractElasticsearchConfiguration {
@Autowired
private RestHighLevelClient restHighLevelClient;
@Override
public RestHighLevelClient elasticsearchClient() {
return restHighLevelClient;
}
@Bean
@Override
public ElasticsearchCustomConversions elasticsearchCustomConversions() {
return new ElasticsearchCustomConversions();
}
@Override
public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter) {
return new ElasticsearchRestTemplate(elasticsearchClient(), elasticsearchConverter) {
@Override
public <T> T execute(ClientCallback<T> callback) {
int retryCount = 0;
T t = null;
while (retryCount <= RestClientBuilder.DEFAULT_MAX_CONN_PER_ROUTE && t == null) {
try {
t = super.execute(callback);
} catch (DataAccessResourceFailureException e) {
// retry
if (e.getCause() != null && (e.getCause().getCause() instanceof SocketTimeoutException) &&
(retryCount < RestClientBuilder.DEFAULT_MAX_CONN_PER_ROUTE)) {
retryCount++;
log.warn("Elasticsearch client - performing retry {} after caught DataAccessResourceFailureException: {}", retryCount, e.getMessage());
}
else {
throw e;
}
}
}
return t;
}
};
}
推荐阅读
- android - Firebase 配置的 Codemagic 预构建问题
- php - AJAX 实时搜索返回 HTTP 500 错误
- angular - 如何将第二个下拉框数据填充到第三个输入框?
- css - 样式化组件中的最小和最大媒体查询
- javascript - 在 docker compose 中运行 sequelize migrates
- mongodb - MongoDB:上限集合中的最大文档数
- java - 通过 Kotlin 使用 Jackson 反序列化对象列表
- node.js - 读取 http 请求正文的性能问题
- firebase - 安装新应用版本后,Firebase 数据库无法正常工作。扑
- parallel-processing - Pytorch - 多个 GPU