请求重试 Apache HttpClient 之间的超时
Timeout between request retries Apache HttpClient
有人可以分享如何配置现代 HttpClient 4.5.3 以重试失败的请求并在每次重试之前等待一段时间吗?
到目前为止,我似乎理解正确 .setRetryHandler(new DefaultHttpRequestRetryHandler(X, false))
将允许重试请求 X 次。
但我不明白如何配置退避:.setConnectionBackoffStrategy()
/ .setBackoffManager()
根据 JavaDocs 规定的其他内容,而不是重试之间的超时。
BackoffManager
/ ConnectionBackoffStrategy
组合可用于根据 I/O 错误率和 503 响应动态增加或减少每个路由的最大连接数限制。它们对请求执行没有影响,不能用于控制请求重新执行
这是使用 HC 4.x API 可以做的最好的事情
CloseableHttpClient client = HttpClientBuilder.create()
.setRetryHandler(new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
return executionCount <= maxRetries &&
exception instanceof SocketException;
}
})
.setServiceUnavailableRetryStrategy(new ServiceUnavailableRetryStrategy() {
@Override
public boolean retryRequest(HttpResponse response, int executionCount, HttpContext context) {
return executionCount <= maxRetries &&
response.getStatusLine().getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE;
}
@Override
public long getRetryInterval() {
return 100;
}
})
.build();
请注意,在出现 I/O 错误或根据请求路由动态调整重试间隔时,目前没有任何优雅的方法可以在请求执行尝试之间强制执行延迟。
关于动态延迟,我想建议的是:
CloseableHttpClient client = HttpClientBuilder.create()
.setRetryHandler(new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
return executionCount <= maxRetries ;
}
})
.setServiceUnavailableRetryStrategy(new ServiceUnavailableRetryStrategy() {
int waitPeriod = 100;
@Override
public boolean retryRequest(HttpResponse response, int executionCount, HttpContext context) {
waitPeriod *= 2;
return executionCount <= maxRetries &&
response.getStatusLine().getStatusCode() >= 500; //important!
}
@Override
public long getRetryInterval() {
return waitPeriod;
}
})
.build();
附录:
请注意,如果出现超时、端口未打开或连接关闭等 IO 错误,则不会调用 ServiceUnavailableRetryStrategy.retryRequest。在这种情况下,只会调用 HttpRequestRetryHandler.retryRequest ,重试将立即或在固定延迟后发生(我最终无法澄清这一点)。所以奥列格的答案实际上是正确的。在 HttpClient 4.5 的支持下无法做到这一点。
(实际上我想将其称为设计错误,因为 IO 错误后的延迟重试在现代微服务环境中至关重要。)
你可以使用 lambda
client.setRetryHandler((e, execCount, httpContext) -> {
if (execCount > tries) {
return false;
} else {
try {
Thread.sleep(recalMillis);
} catch (InterruptedException ex) {
//ignore
}
return true;
}
请注意,处理程序仅适用于 IOExceptions 类型
有人可以分享如何配置现代 HttpClient 4.5.3 以重试失败的请求并在每次重试之前等待一段时间吗?
到目前为止,我似乎理解正确 .setRetryHandler(new DefaultHttpRequestRetryHandler(X, false))
将允许重试请求 X 次。
但我不明白如何配置退避:.setConnectionBackoffStrategy()
/ .setBackoffManager()
根据 JavaDocs 规定的其他内容,而不是重试之间的超时。
BackoffManager
/ ConnectionBackoffStrategy
组合可用于根据 I/O 错误率和 503 响应动态增加或减少每个路由的最大连接数限制。它们对请求执行没有影响,不能用于控制请求重新执行
这是使用 HC 4.x API 可以做的最好的事情
CloseableHttpClient client = HttpClientBuilder.create()
.setRetryHandler(new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
return executionCount <= maxRetries &&
exception instanceof SocketException;
}
})
.setServiceUnavailableRetryStrategy(new ServiceUnavailableRetryStrategy() {
@Override
public boolean retryRequest(HttpResponse response, int executionCount, HttpContext context) {
return executionCount <= maxRetries &&
response.getStatusLine().getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE;
}
@Override
public long getRetryInterval() {
return 100;
}
})
.build();
请注意,在出现 I/O 错误或根据请求路由动态调整重试间隔时,目前没有任何优雅的方法可以在请求执行尝试之间强制执行延迟。
关于动态延迟,我想建议的是:
CloseableHttpClient client = HttpClientBuilder.create()
.setRetryHandler(new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
return executionCount <= maxRetries ;
}
})
.setServiceUnavailableRetryStrategy(new ServiceUnavailableRetryStrategy() {
int waitPeriod = 100;
@Override
public boolean retryRequest(HttpResponse response, int executionCount, HttpContext context) {
waitPeriod *= 2;
return executionCount <= maxRetries &&
response.getStatusLine().getStatusCode() >= 500; //important!
}
@Override
public long getRetryInterval() {
return waitPeriod;
}
})
.build();
附录: 请注意,如果出现超时、端口未打开或连接关闭等 IO 错误,则不会调用 ServiceUnavailableRetryStrategy.retryRequest。在这种情况下,只会调用 HttpRequestRetryHandler.retryRequest ,重试将立即或在固定延迟后发生(我最终无法澄清这一点)。所以奥列格的答案实际上是正确的。在 HttpClient 4.5 的支持下无法做到这一点。
(实际上我想将其称为设计错误,因为 IO 错误后的延迟重试在现代微服务环境中至关重要。)
你可以使用 lambda
client.setRetryHandler((e, execCount, httpContext) -> {
if (execCount > tries) {
return false;
} else {
try {
Thread.sleep(recalMillis);
} catch (InterruptedException ex) {
//ignore
}
return true;
}
请注意,处理程序仅适用于 IOExceptions 类型