标题:
HttpClient重试机制 --自定义HttpRequestRetryHandler
[打印本页]
作者:
look_w
时间:
2019-4-12 13:42
标题:
HttpClient重试机制 --自定义HttpRequestRetryHandler
通过http做接口调用请求的时候,常常会因为网络抖动或者其他未知原因,造成接口在某个瞬间访问不了。此时需要增加重试机制。
HttpClient有重试机制,通过设置httpclient 的retryHandler来实现。
封装了一个HttpClientUtils的工具类中的获取线程池并设置retry机制的方法,代码如下:
package com.ly.storm.config;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.NameValuePair;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.PostConstruct;
import javax.net.ssl.SSLException;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
/**
* @Auther: fc.w
* @Date: 2018/12/12
*/
public class HttpClientUtils {
private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class);
private static final RequestConfig REQUEST_CONFIG_TIME_OUT = RequestConfig.custom()
.setSocketTimeout(20000)
.setConnectTimeout(50000)
.setConnectionRequestTimeout(50000)
.build();
private static PoolingHttpClientConnectionManager cm = null;
@PostConstruct
public void init() {
cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(1000);
cm.setDefaultMaxPerRoute(1000);
}
/**
*
* @param isPooled 是否使用连接池
* @return
*/
public static CloseableHttpClient getClient(boolean isPooled) {
HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException e, int retryTimes, HttpContext httpContext) {
if (retryTimes > 2) {
return false;
}
if (e instanceof UnknownHostException || e instanceof ConnectTimeoutException
|| !(e instanceof SSLException) || e instanceof NoHttpResponseException) {
return true;
}
HttpClientContext clientContext = HttpClientContext.adapt(httpContext);
HttpRequest request = clientContext.getRequest();
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
if (idempotent) {
// 如果请求被认为是幂等的,那么就重试。即重复执行不影响程序其他效果的
return true;
}
return false;
}
};
if (isPooled) {
return HttpClients.custom().setConnectionManager(cm).setRetryHandler(retryHandler).build();
}
return HttpClients.createDefault();
}
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/)
Powered by Discuz! 7.0.0