古いプロジェクトは、リクエストの送信に Java ネイティブの java.net パッケージを使用しており、古すぎるため、パフォーマンスが httpclient ほど良くありません。httpclient を使用するプロセスでは、再試行回数の設定が比較的簡単で、再試行回数もそれほど多くありません。インターネット上にはリトライ間隔がたくさんあり、2日間このリトライ間隔問題に悩まされてきたので、今日は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 つの点の違いを個人的に理解しています。HttpRequestRetryHandler
が異常である、リクエストの送信が失敗またはタイムアウトするなど、ServiceUnavailableRetryStrategy 関数が
リクエストを正常に送信していること、通常は IP とポートを介して Telnet でき、再試行が必要かどうかを判断することです。返されたステータス コードに応じて、再試行間隔を設定できます。再試行時のデフォルトのステータス コードは 503 です。!!
以上
参考リンク:
https://blog.csdn.net/chenzenan/article/details/84945114