HttpClient线程池&重试机制
HttpClientUtils
package com.example.http_thread.util;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.ServiceUnavailableRetryStrategy;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import javax.net.ssl.SSLException;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;
public class HttpClientUtil {
private static PoolingHttpClientConnectionManager cm = null;
static {
cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(200);//多线程调用注意配置,根据线程数设定
cm.setDefaultMaxPerRoute(300);
}
public static CloseableHttpClient getHttpClient() {
HttpRequestRetryHandler httpRequestRetryHandler=new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException e, int i, HttpContext httpContext) {
//Date date=new Date();
System.out.println("try httpRequestRetryHandler o: " +i);
if (i >= 10000) {
// Do not retry if over max retry count
return false;
}
if (e instanceof InterruptedIOException) {
// Timeout
return true;
}
if (e instanceof UnknownHostException) {
// Unknown host
return false;
}
if (e instanceof ConnectTimeoutException) {
// Connection refused
return true;
}
if (e instanceof SSLException) {
// SSL handshake exception
return false;
}
HttpClientContext clientContext = HttpClientContext.adapt(httpContext);
HttpRequest request = clientContext.getRequest();
boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
if (idempotent) {
// Retry if the request is considered idempotent
return true;
}
return false;
}
};
CloseableHttpClient httpClient = HttpClients.custom().setRetryHandler(httpRequestRetryHandler)
.setConnectionManager(cm)
.build();
return httpClient;
}
}
如何配置使用
@Test
void testThreads() {
String url = "*********************************";
CloseableHttpClient client = HttpClientUtil.getHttpClient();
HttpGet request = new HttpGet(url);
CloseableHttpResponse response = null;
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(20000)//数据传输过程中数据包之间间隔的最大时间
.setConnectTimeout(200000)//连接建立时间,三次握手完成时间
.setExpectContinueEnabled(true)//重点参数
.setConnectionRequestTimeout(60000)
.setStaleConnectionCheckEnabled(true)//重点参数,在请求之前校验链接是否有效
.build();
request.setConfig(requestConfig);
System.out.println("111111111111111111111111111111111111");
try {
response = client.execute(request);
System.out.println("22222222222222222222222222222222");
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
System.out.println("请求失败");
}
HttpEntity resEntity = response.getEntity();
if (resEntity == null) {
System.out.println("No Response");
}
String result = EntityUtils.toString(resEntity, "UTF-8");
} catch (Exception e) {
System.out.println("0123123312"+e.getMessage()+e.getClass());
}
finally {
if (response != null) {
try {
//此处调优重点,多线程模式下可提高性能。
EntityUtils.consume(response.getEntity());//此处高能,通过源码分析,由EntityUtils是否回收HttpEntity
response.close();
} catch (IOException e) {
System.out.println("关闭response失败:" + e);
}
}
}
}