Timeout between request retries Apache HttpClient

僤鯓⒐⒋嵵緔 提交于 2019-12-06 07:20:15

问题


Could somebody share how to configure modern HttpClient 4.5.3 to retry failed requests and wait for some time before each retry?

So far it looks like I got it correctly that .setRetryHandler(new DefaultHttpRequestRetryHandler(X, false)) will allow to retry requests X times.

But I cannot understand how to configure backoff: .setConnectionBackoffStrategy() / .setBackoffManager() according to JavaDocs regulate something else, not timeout between retries.


回答1:


About the dynamic delay, I want to suggest this:

CloseableHttpClient client = HttpClientBuilder.create()
    .setRetryHandler(new HttpRequestRetryHandler() {
        @Override
        public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
            return executionCount <= maxRetries ;
        }
    })
    .setServiceUnavailableRetryStrategy(new ServiceUnavailableRetryStrategy() {
        int waitPeriod = 100;
        @Override
        public boolean retryRequest(HttpResponse response, int executionCount, HttpContext context) {
            waitPeriod *= 2;
            return executionCount <= maxRetries &&
               response.getStatusLine().getStatusCode() >= 500; //important!
        }

        @Override
        public long getRetryInterval() {
            return waitPeriod;
        }
    })
    .build();

Appendix: Please note, that ServiceUnavailableRetryStrategy.retryRequest will NOT be called, if there was an IO error like timeout, port not open or connection closed. In such cases, only HttpRequestRetryHandler.retryRequest will be called, and the retry will happen either immediately or after a fixed delay (I could not finally clarify this). So oleg's answer is actually the right one. There is no way to do it with support of HttpClient 4.5.

(I would actually like to call this a design bug, as delayed retries after an IO error are vitally important in a modern microservice environment.)




回答2:


BackoffManager / ConnectionBackoffStrategy combo can be used to dynamically increase or decrease max connection per route limits based on rate of I/O errors and 503 responses. They have no influence on request execution and cannot be used to control request re-execution

This is the best one can do with HC 4.x APIs

CloseableHttpClient client = HttpClientBuilder.create()
        .setRetryHandler(new HttpRequestRetryHandler() {
            @Override
            public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
                return executionCount <= maxRetries &&
                        exception instanceof SocketException;
            }
        })
        .setServiceUnavailableRetryStrategy(new ServiceUnavailableRetryStrategy() {
            @Override
            public boolean retryRequest(HttpResponse response, int executionCount, HttpContext context) {
                return executionCount <= maxRetries &&
                        response.getStatusLine().getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE;
            }

            @Override
            public long getRetryInterval() {
                return 100;
            }
        })
        .build();

Please note there is presently no elegant way of enforcing a delay between request execution attempts in case of an I/O error or dynamically adjusting the retry interval based on request route.




回答3:


You can use lambda

client.setRetryHandler((e, execCount, httpContext) -> {
                if (execCount > tries) {
                    return false;
                } else {
                    try {
                        Thread.sleep(recalMillis);
                    } catch (InterruptedException ex) {
                        //ignore
                    }
                    return true;
                }

Notice that handler works only for IOExceptions types



来源:https://stackoverflow.com/questions/48541329/timeout-between-request-retries-apache-httpclient

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!