老项目使用java原生的java.net包作发送请求的方式太老了,并且性能也没httpclient好,在使用httpclient的过程中,设置重试次数比较简单,设置重试时间间隔网上不是太多,并且我被这个重试时间间隔问题困扰了两天,今天就记录一下,如何用ServiceUnavailableRetryStrategy设置重试间隔时间!!!
上代码
//工具类
public class PayHttpUtils {
private static ServiceUnavailableRetryStrategy serviceUnavailableRetryStrategy=null;
private static PoolingHttpClientConnectionManager cm=null;
private static HttpRequestRetryHandler httpRequestRetryHandler =null;
static {
log.addTrace("PayHttpUtils工具类静态代码块初始化!" );
httpRequestRetryHandler = new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int retryTimes, HttpContext context) {
log.addError("httpclient重试机制入参:exception:" + exception + " retryTimes:" + retryTimes + " context:" + context);
String retryNum = ConfigAlipay.getMessage("retryNum");
if(StringUtil.isEmpty(retryNum)){
retryNum = "3";
}
log.addError("重试次数为:" + retryNum);
if (retryTimes >= Integer.parseInt(retryNum)) {
return false;
}
if (exception instanceof ConnectTimeoutException || exception instanceof NoHttpResponseException || exception instanceof SocketTimeoutException
|| !(exception instanceof UnknownHostException) || !(exception instanceof InterruptedIOException) || !(exception instanceof SSLException)
|| !(exception instanceof SSLHandshakeException)) {
return true;
}else {
log.addError("未记录的请求异常:" + exception.getClass());
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
if (idempotent) {
// 如果请求被认为是幂等的,那么就重试。即重复执行不影响程序其他效果的
return true;
}
return false;
}
};
serviceUnavailableRetryStrategy = new ServiceUnavailableRetryStrategy() {
/**
* retry逻辑
*/
@Override
public boolean retryRequest(HttpResponse response, int executionCount, HttpContext context) {
log.addError("retryRequest次数为:"+executionCount);
String retryNum = ConfigAlipay.getMessage("retryNum");
if(StringUtil.isEmpty(retryNum)){
retryNum = "3";
}
//当返回状态码不为200(成功)的情况下重试,重试次数默认设为3次
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK && executionCount <= Integer.parseInt(retryNum))
return true;
else
return false;
}
/**
* retry间隔时间
*/
@Override
public long getRetryInterval() {
log.addError("getRetryInterval");
String retryInterval = ConfigAlipay.getMessage("retryInterval");
if(StringUtil.isEmpty(retryInterval)){
retryInterval = "1000";
}
log.addError("重试时间间隔为:" + retryInterval);
return Long.parseLong(retryInterval);
}
};
cm = new PoolingHttpClientConnectionManager();
//连接池最大生成连接数200
cm.setMaxTotal(200);
//默认设置route最大连接数
cm.setDefaultMaxPerRoute(100);
}
public static CloseableHttpClient createSSLClientDefault(Boolean bool) {
try {
if (bool){
log.addTrace("此请求为https方式!");
return HttpsSSLClient.createSSLInsecureClient(cm,httpRequestRetryHandler,serviceUnavailableRetryStrategy);
}
} catch (Exception e) {
e.printStackTrace();
}
log.addTrace("此请求为http方式!");
return HttpClients.custom().setConnectionManager(cm).setRetryHandler(httpRequestRetryHandler).setServiceUnavailableRetryStrategy(serviceUnavailableRetryStrategy).build();
}
获取Https 请求客户端代码:
/**
* 获取Https 请求客户端
* @return
*/
public static CloseableHttpClient createSSLInsecureClient(PoolingHttpClientConnectionManager cm,HttpRequestRetryHandler httpRequestRetryHandler,ServiceUnavailableRetryStrategy serviceUnavailableRetryStrategy) {
SSLContext sslcontext = createSSLContext();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext, new MyHostnameVerifier());
return HttpClients.custom().setConnectionManager(cm).setRetryHandler(httpRequestRetryHandler).setServiceUnavailableRetryStrategy(serviceUnavailableRetryStrategy).setSSLSocketFactory(sslsf).build();
}
原理,其实就是:
1.重写HttpRequestRetryHandler接口实现有异常了就重试,可以自定义重试次数和异常种类
2.重写ServiceUnavailableRetryStrategy接口实现根据响应码设置重试次数和重试时间间隔
个人理解上面两点的区别:
HttpRequestRetryHandler是出现异常了,发送请求失败或者超时等,起作用
ServiceUnavailableRetryStrategy是发送请求成功,一般能telnet通ip和端口,根据返回的状态码来判断是否需要重试,并且可设置重试时间间隔,默认状态码是503的时候重试!!!
over
参考连接:
https://blog.csdn.net/chenzenan/article/details/84945114