ES Rest 高级客户端在空闲一段时间后抛出 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]

RestHighLevelClient 是使用以下方法创建的:


    @Bean

    RestHighLevelClient client() {


        ClientConfiguration clientConfiguration = ClientConfiguration.builder()

                .connectedTo(elasticsearchHostAndPort)

                .build();


        return RestClients.create(clientConfiguration).rest();

    }

spring-data-elasticsearch3.2.0.M2使用的版本。


任何提示/解决方法?


斯蒂芬大帝
浏览 1398回答 5
5回答

呼啦一阵风

我也尝试过将连接/套接字超时设置为 0,如此处和其他地方所建议的那样。它最终没有帮助。还有另一种解决方案/解决方法,由 spring-data-elasticsearch 在 https://jira.spring.io/browse/DATAES-789中建议。如果出现此类异常,它只会执行内部重试。它并没有真正解决问题,但您的客户不会收到错误消息。相反,空闲时间后的第一个请求将额外花费 5 秒(或您配置的任何超时)。如果你使用的是springboot-data-elasticsearch version 4+(从Springboot 2.3.0开始),那么你就可以应用该方案。我可以确认以下解决方案有效(具有我上面提到的限制):@Configurationpublic class ElasticSearchRestClientConfig extends AbstractElasticsearchConfiguration {&nbsp; &nbsp; @Autowired&nbsp; &nbsp; private RestHighLevelClient restHighLevelClient;&nbsp; &nbsp; @Override&nbsp; &nbsp; public RestHighLevelClient elasticsearchClient() {&nbsp; &nbsp; &nbsp; &nbsp; return restHighLevelClient;&nbsp; &nbsp; }&nbsp; &nbsp; @Bean&nbsp; &nbsp; @Override&nbsp; &nbsp; public ElasticsearchCustomConversions elasticsearchCustomConversions() {&nbsp; &nbsp; &nbsp; &nbsp; return new ElasticsearchCustomConversions();&nbsp; &nbsp; }&nbsp; &nbsp; @Override&nbsp; &nbsp; public ElasticsearchOperations elasticsearchOperations(ElasticsearchConverter elasticsearchConverter) {&nbsp; &nbsp; &nbsp; &nbsp; return new ElasticsearchRestTemplate(elasticsearchClient(), elasticsearchConverter) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public <T> T execute(ClientCallback<T> callback) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; int retryCount = 0;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; T t = null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (retryCount <= RestClientBuilder.DEFAULT_MAX_CONN_PER_ROUTE && t == null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; t = super.execute(callback);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (DataAccessResourceFailureException e) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // retry&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (e.getCause() != null && (e.getCause().getCause() instanceof SocketTimeoutException) &&&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (retryCount < RestClientBuilder.DEFAULT_MAX_CONN_PER_ROUTE)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; retryCount++;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.warn("Elasticsearch client - performing retry {} after caught DataAccessResourceFailureException: {}", retryCount, e.getMessage());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw e;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return t;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; }&nbsp;

浮云间

在RestClientBuilder.createHttpClient()默认情况下,套接字超时和连接超时设置为 30 和 10 秒。您可以通过实施RestClientBuilder.RequestConfigCallback和调用 setRequestConfigCallback(...)您的RestHighLevelClient我们做了类似的事情@Overridepublic RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder builder) {&nbsp; &nbsp; return builder.setSocketTimeout(socketTimeout); // try to prevent SocketTimeoutException}

慕森王

这是我解决这个问题的方法:@Configuration@EnableElasticsearchRepositories(basePackages = "com.hamdos.repositories.es")@ComponentScan(basePackages = { "com.hamdos.services.es" })@Order(2)public class Config {&nbsp; &nbsp; @Bean&nbsp; &nbsp; RestHighLevelClient client() {&nbsp; &nbsp; &nbsp; &nbsp; RestClientBuilder builder = RestClient.builder(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new HttpHost("localhost", 9289))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .setRequestConfigCallback(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new RestClientBuilder.RequestConfigCallback() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public RequestConfig.Builder customizeRequestConfig(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RequestConfig.Builder requestConfigBuilder) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return requestConfigBuilder&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .setConnectTimeout(5000)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .setSocketTimeout(60000);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; return new RestHighLevelClient(builder);&nbsp; &nbsp; }&nbsp; &nbsp; @Bean&nbsp; &nbsp; public ElasticsearchOperations elasticsearchTemplate() {&nbsp; &nbsp; &nbsp; &nbsp; return new ElasticsearchRestTemplate(client());&nbsp; &nbsp; }}

HUWWW

&nbsp;@Beanoverride fun elasticsearchClient(): RestHighLevelClient {&nbsp; &nbsp; val clientConfiguration = ClientConfiguration&nbsp; &nbsp; &nbsp; &nbsp; .builder()&nbsp; &nbsp; &nbsp; &nbsp; .connectedTo("localhost:9200")&nbsp; &nbsp; &nbsp; &nbsp; .withSocketTimeout(enter time in millisecond)&nbsp; &nbsp; &nbsp; &nbsp; .build()`enter code here`&nbsp; &nbsp; return RestClients.create(clientConfiguration).rest()}只需像上面显示的那样使用 withSocketTimeout(30000) mthode

料青山看我应如是

它也应该可以通过属性进行配置:spring.elasticsearch.jest.connection-timeout=3000&nbsp;#&nbsp;Connection&nbsp;timeout&nbsp;in&nbsp;milliseconds. spring.elasticsearch.jest.multi-threaded=true&nbsp;#&nbsp;Enable&nbsp;connection&nbsp;requests&nbsp;from&nbsp;multiple&nbsp;execution&nbsp;threads.
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java