ES Rest High Level Client throws SocketTimeoutException after being idle for sometime
I have also tried setting the connection/socket timeout to 0, as suggested here and in other places. It didn't help eventually.
There is another solution/workaround, suggested by spring-data-elasticsearch in https://jira.spring.io/browse/DATAES-789. It simply perform an internal retry in case of such exception. It does not really solve the issue, but your client will not get and error. Instead, the first request after idle time will take additional 5 seconds (or whatever timeout your configured).
If you use Springboot-data-elasticsearch version 4+ (staring with Springboot 2.3.0), then you can apply the solution.
I can confirm the following solution is working (with the limitations I mentioned above):
@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;
}
};
}
In RestClientBuilder.createHttpClient()
the defaults for socket timeout and connection timeout are set to 30 and 10 seconds.
You can override this defaults by implementing RestClientBuilder.RequestConfigCallback
and calling setRequestConfigCallback(...)
on your RestHighLevelClient
We did something like
@Override
public RequestConfig.Builder customizeRequestConfig(RequestConfig.Builder builder) {
return builder.setSocketTimeout(socketTimeout); // try to prevent SocketTimeoutException
}