feilong
feilong copied to clipboard
httpclient 支持retry功能
httpclient 支持retry功能
org.apache.http.impl.client.HttpClientBuilder.build() L1128
// Add request retry executor, if not disabled
if (!automaticRetriesDisabled) {
HttpRequestRetryHandler retryHandlerCopy = this.retryHandler;
if (retryHandlerCopy == null) {
retryHandlerCopy = DefaultHttpRequestRetryHandler.INSTANCE;
}
execChain = new RetryExec(execChain, retryHandlerCopy);
}
关于 org.apache.http.impl.execchain.RetryExec.execute(HttpRoute, HttpRequestWrapper, HttpClientContext, HttpExecutionAware)
其中 是否 可重复 请求是否可重复
RequestEntityProxy.isRepeatable(HttpRequest)
static boolean isRepeatable(final HttpRequest request) {
if (request instanceof HttpEntityEnclosingRequest) {
final HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
if (entity != null) {
if (isEnhanced(entity)) {
final RequestEntityProxy proxy = (RequestEntityProxy) entity;
if (!proxy.isConsumed()) {
return true;
}
}
return entity.isRepeatable();
}
}
return true;
}
put / post /patch 是HttpEntityEnclosingRequest
子类, 其他直接返回true
关于 HttpEntity
post requestBody 是使用的 StringEntity
param 使用的是 UrlEncodedFormEntity 是StringEntity 的子类
然后 判断 entity.isRepeatable()
-
org.apache.http.entity.StringEntity.isRepeatable()
-
org.apache.http.entity.ByteArrayEntity.isRepeatable()
-
org.apache.http.entity.EntityTemplate.isRepeatable()
-
org.apache.http.entity.FileEntity.isRepeatable()
-
org.apache.http.entity.SerializableEntity.isRepeatable()
是true
-
org.apache.http.entity.BasicHttpEntity.isRepeatable()
-
org.apache.http.entity.InputStreamEntity.isRepeatable()
是false
默认使用 org.apache.http.impl.client.DefaultHttpRequestRetryHandler
自动重连3次
默认
InterruptedIOException.class,
UnknownHostException.class,
ConnectException.class,
SSLException.class
4个不重试
而 SocketTimeoutException 正好属于 InterruptedIOException

dingtalk 是post 请求
//---------------------------------------------------------------
HttpRequest httpRequest = new HttpRequest(BOT_WEBHOOK_URL, POST);
https://blog.csdn.net/shope9/article/details/124047321
默认 不是幂等的请求不重试
HttpClient默认是有重试机制的,其重试策略是:
1.只有发生IOExecetion时才会发生重试
2.InterruptedIOException、UnknownHostException、ConnectException、SSLException,发生这4中异常不重试
3.get方法可以重试3次,post方法在socket对应的输出流没有被write并flush成功时可以重试3次。
4.读/写超时不进行重试
5.socket传输中被重置或关闭会进行重试
6.以及一些其他的IOException,暂时分析不出来。
StandardHttpRequestRetryHandler
According to RFC-2616 section 9.1.2 the idempotent HTTP methods are: GET, HEAD, PUT, DELETE, OPTIONS, and TRACE
都会去重试
