RPC 框架层出不穷,但是说起鼻祖那一定是来自于 apache 的 httpClient。
RPC 框架的一个重要特征就是要解决因网络失败导致超时问题,换句话说就是要支持重试机制。httpClient 也不例外。
httpClient 是通过 retryHandler 来实现重试的。当请求过程出现异常时,你可以选择是否自动重试。
下面就看下具体使用步骤:
一. 定义 retryHandler
HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
public boolean retryRequest(
IOException exception,
int executionCount,
HttpContext context) {
System.out.println(Thread.currentThread().getName()+ " try request: " + executionCount);
if (executionCount >= 5) {
// Do not retry if over max retry count
return false;
}
if (exception instanceof InterruptedIOException) {
// Timeout
return false;
}
if (exception instanceof UnknownHostException) {
// Unknown host, 通常不用重试,这里暂时返回 true 测试使用
return true;
}
if (exception instanceof ConnectTimeoutException) {
// Connection refused
return false;
}
if (exception instanceof SSLException) {
// SSL handshake exception
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(context);
HttpRequest request = clientContext.getRequest();
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
if (idempotent) {
// Retry if the request is considered idempotent
return true;
}
return false;
}
};
二. 创建 httpClient,并添加 retryHandler
// 助力这里使用的是 CloseableHttpClient
CloseableHttpClient httpclient = HttpClients.custom()
.setRetryHandler(myRetryHandler)
.build();
三. 测试
public static void main(String... args) throws IOException {
try {
// 故意写错主机名测试
HttpGet httpget = new HttpGet("http://localhosts:8080");
System.out.println("Executing request " + httpget.getRequestLine());
httpclient.execute(httpget);
System.out.println("Request finished");
} catch (IOException e) {
// throw e;
} finally {
}
}
四. 总结:
1. 无论使用过程异常是否捕捉处理,都会重试;
2. 达到最大重试次数后会将异常抛出,执行线程退出。
如果觉得还不错的话,关注、分享、在看(关注不失联~), 原创不易,且看且珍惜~