Java 如何在Apache httpclient上使用指数退避策略?
指定了一类指数BackOffSchedulingStrategy,但它在4.5版中似乎不存在 而且,没有找到任何解释如何使用它的东西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
以前有人使用过类似的东西吗?如果您使用这样的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;iExponentialBackOffSchedulingStrategy
对缓存项有效,这就是为什么它只能用于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”方法中的失败。看起来您需要对这两个类进行子类化以覆盖此行为。