Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/apache/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在Apache httpclient上使用指数退避策略?_Java_Apache_Httpclient - Fatal编程技术网

Java 如何在Apache httpclient上使用指数退避策略?

Java 如何在Apache httpclient上使用指数退避策略?,java,apache,httpclient,Java,Apache,Httpclient,指定了一类指数BackOffSchedulingStrategy,但它在4.5版中似乎不存在 而且,没有找到任何解释如何使用它的东西 以前有人使用过类似的东西吗?如果您使用这样的Maven包(Grails Maven依赖语法)安装Apache HTTP Client 4.5.x: 您需要添加另一个jar来获取这些类,如下所示: compile 'org.apache.httpcomponents:httpclient-cache:4.5.1' import org.apache.http.i

指定了一类指数BackOffSchedulingStrategy,但它在4.5版中似乎不存在

而且,没有找到任何解释如何使用它的东西


以前有人使用过类似的东西吗?

如果您使用这样的Maven包(Grails Maven依赖语法)安装Apache HTTP Client 4.5.x:

您需要添加另一个jar来获取这些类,如下所示:

compile 'org.apache.httpcomponents:httpclient-cache:4.5.1'
 import org.apache.http.impl.client.*;
 import org.apache.http.impl.client.cache.*;
 import org.apache.http.client.methods.*;

 CloseableHttpClient createClient() {
     CachingHttpClientBuilder hcb = new CachingHttpClientBuilder();
     CacheConfig cc = CacheConfig.DEFAULT;
     ExponentialBackOffSchedulingStrategy ebo = new ExponentialBackOffSchedulingStrategy(cc);
     hcb.setSchedulingStrategy(ebo);
     CloseableHttpClient hc = hcb.build();
     return hc;
 }

 // You'll need to replace the URL below with something that returns a 5xx error
 CloseableHttpClient client = createClient();
 HttpUriRequest request = new HttpGet("http://www.example.com/throwsServerError");
 for (int i=0; i<4; i++) {
     CloseableHttpResponse response =  client.execute(request);
     println new Date().toString() + " " + response.getStatusLine().getStatusCode();
 }

然后你可以像这样把它连接起来:

compile 'org.apache.httpcomponents:httpclient-cache:4.5.1'
 import org.apache.http.impl.client.*;
 import org.apache.http.impl.client.cache.*;
 import org.apache.http.client.methods.*;

 CloseableHttpClient createClient() {
     CachingHttpClientBuilder hcb = new CachingHttpClientBuilder();
     CacheConfig cc = CacheConfig.DEFAULT;
     ExponentialBackOffSchedulingStrategy ebo = new ExponentialBackOffSchedulingStrategy(cc);
     hcb.setSchedulingStrategy(ebo);
     CloseableHttpClient hc = hcb.build();
     return hc;
 }

 // You'll need to replace the URL below with something that returns a 5xx error
 CloseableHttpClient client = createClient();
 HttpUriRequest request = new HttpGet("http://www.example.com/throwsServerError");
 for (int i=0; i<4; i++) {
     CloseableHttpResponse response =  client.execute(request);
     println new Date().toString() + " " + response.getStatusLine().getStatusCode();
 }
import org.apache.http.impl.client.*;
导入org.apache.http.impl.client.cache.*;
导入org.apache.http.client.methods.*;
CloseableHttpClient createClient(){
CachingHttpClientBuilder hcb=新的CachingHttpClientBuilder();
CacheConfig cc=CacheConfig.DEFAULT;
指数打包策略ebo=新指数打包策略(cc);
hcb.设置检查策略(ebo);
CloseableHttpClient hc=hcb.build();
返回hc;
}
//您需要将下面的URL替换为返回5xx错误的URL
CloseableHttpClient=createClient();
HttpUriRequest请求=新的HttpGet(“http://www.example.com/throwsServerError");

对于(int i=0;i
ExponentialBackOffSchedulingStrategy
对缓存项有效,这就是为什么它只能用于
CachingClient
。我认为它不能用于在请求失败时实现指数退避重试机制

我将按照以下思路实施一个简单的指数退避策略:

类MyExponentialBackoffRetryHandler扩展了HttpRequestRetryHandler{
公共MyExponentialBackoffRetryHandler(int-maxNumRetries、int-backOffRate、int-InitialExpire、int-MaxExpire){
} 
boolean retryRequest(IOException异常、int executionCount、HttpContext上下文){
if(executionCount==maxNumRetries){
返回false;
}否则{
long nextBackOffDelay=initialexpirement*Math.pow(退避率、执行计数-
1)
长延迟=数学最小值(maxExpiry,nextBackOffDelay)
睡眠(延迟);
返回true;
} 
}
}
此外,为了触发重试,您需要添加一个抛出
IOException
的响应拦截器,例如:

类MyResponseInterceptor扩展了HttpResponseInterceptor{
无效进程(HttpResponse响应,HttpContext上下文)抛出HttpException,IOException{
如果(response.getStatusLine.getStatusCode==503){
抛出新IOException(“请重试”)
}
}
}
最后,您可以构建HTTP客户端实例,如下所示:

HttpClientBuilder
.create()
.setRetryHandler(新的MyExponentialBackoffRetryHandler(…)
.addInterceptorFirst(新的MyResponseInterceptor())
.build()

通过向
https://httpstat.us/503

默认情况下,它会立即重试,然后以6s的10/6s的幂次重试,直到在6个循环中耗尽。谢谢!如果我想在状态代码4xx上重试,该怎么办?我找不到自定义的方法。@IronManZ它似乎有一个方法“decorateMainExec”它创建一个实例,该类控制其“isIncompleteResponse”方法中的失败。看起来您需要对这两个类进行子类化以覆盖此行为。