为了账号安全,请及时绑定邮箱和手机立即绑定

ES Rest 高级客户端在空闲一段时间后抛出 SocketTimeoutException

ES Rest 高级客户端在空闲一段时间后抛出 SocketTimeoutException

斯蒂芬大帝 2023-02-23 16:50:16
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] wjava.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使用的版本。任何提示/解决方法?
查看完整描述

5 回答

?
呼啦一阵风

TA贡献1802条经验 获得超6个赞

我也尝试过将连接/套接字超时设置为 0,如此处和其他地方所建议的那样。它最终没有帮助。


还有另一种解决方案/解决方法,由 spring-data-elasticsearch 在 https://jira.spring.io/browse/DATAES-789中建议。如果出现此类异常,它只会执行内部重试。它并没有真正解决问题,但您的客户不会收到错误消息。相反,空闲时间后的第一个请求将额外花费 5 秒(或您配置的任何超时)。


如果你使用的是springboot-data-elasticsearch version 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;

            }

        };

    }

 


查看完整回答
反对 回复 2023-02-23
?
浮云间

TA贡献1829条经验 获得超4个赞

在RestClientBuilder.createHttpClient()默认情况下,套接字超时和连接超时设置为 30 和 10 秒。


您可以通过实施RestClientBuilder.RequestConfigCallback和调用 setRequestConfigCallback(...)您的RestHighLevelClient


我们做了类似的事情


@Override

public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder builder) {

    return builder.setSocketTimeout(socketTimeout); // try to prevent SocketTimeoutException

}


查看完整回答
反对 回复 2023-02-23
?
慕森王

TA贡献1777条经验 获得超3个赞

这是我解决这个问题的方法:


@Configuration

@EnableElasticsearchRepositories(basePackages = "com.hamdos.repositories.es")

@ComponentScan(basePackages = { "com.hamdos.services.es" })

@Order(2)

public class Config {


    @Bean

    RestHighLevelClient client() {


        RestClientBuilder builder = RestClient.builder(

                new HttpHost("localhost", 9289))

                .setRequestConfigCallback(

                        new RestClientBuilder.RequestConfigCallback() {

                            @Override

                            public RequestConfig.Builder customizeRequestConfig(

                                    RequestConfig.Builder requestConfigBuilder) {

                                return requestConfigBuilder

                                        .setConnectTimeout(5000)

                                        .setSocketTimeout(60000);

                            }

                        });


        return new RestHighLevelClient(builder);

    }


    @Bean

    public ElasticsearchOperations elasticsearchTemplate() {

        return new ElasticsearchRestTemplate(client());

    }

}


查看完整回答
反对 回复 2023-02-23
?
HUWWW

TA贡献1874条经验 获得超12个赞

 @Bean

override fun elasticsearchClient(): RestHighLevelClient {

    val clientConfiguration = ClientConfiguration

        .builder()

        .connectedTo("localhost:9200")

        .withSocketTimeout(enter time in millisecond)

        .build()`enter code here`

    return RestClients.create(clientConfiguration).rest()

}

只需像上面显示的那样使用 withSocketTimeout(30000) mthode


查看完整回答
反对 回复 2023-02-23
?
料青山看我应如是

TA贡献1772条经验 获得超7个赞

它也应该可以通过属性进行配置:

spring.elasticsearch.jest.connection-timeout=3000 # Connection timeout in milliseconds.
spring.elasticsearch.jest.multi-threaded=true # Enable connection requests from multiple execution threads.



查看完整回答
反对 回复 2023-02-23
  • 5 回答
  • 0 关注
  • 996 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信