| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- package com.uas.ps.inquiry.http;
- import org.apache.http.HttpEntityEnclosingRequest;
- import org.apache.http.HttpRequest;
- import org.apache.http.NoHttpResponseException;
- import org.apache.http.client.HttpRequestRetryHandler;
- import org.apache.http.client.config.RequestConfig;
- import org.apache.http.client.protocol.HttpClientContext;
- import org.apache.http.impl.client.CloseableHttpClient;
- import org.apache.http.impl.client.HttpClients;
- import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
- import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
- import org.apache.http.impl.nio.client.HttpAsyncClients;
- import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
- import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
- import org.apache.http.impl.nio.reactor.IOReactorConfig;
- import org.apache.http.nio.reactor.ConnectingIOReactor;
- import org.apache.http.nio.reactor.IOReactorException;
- import org.apache.http.protocol.HttpContext;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.stereotype.Component;
- import javax.annotation.PostConstruct;
- import javax.net.ssl.SSLException;
- import javax.net.ssl.SSLHandshakeException;
- import java.io.IOException;
- import java.io.InterruptedIOException;
- import java.net.SocketException;
- /**
- * http 同步连接池、http 异步连接池,与spring集成
- * @author liuam
- * @since 2018/8/27 0027 下午 15:58
- */
- @Component
- public class HttpClientSpringFactory {
- private static final Logger logger = LoggerFactory.getLogger(HttpClientSpringFactory.class);
- @Value("${http.asyncConnectTimeout}")
- private Integer asyncConnectTimeout;
- @Value("${http.asyncSocketTimeout}")
- private Integer asyncSocketTimeout;
- @Value("${http.asyncConnectionRequestTimeout}")
- private Integer asyncConnectionRequestTimeout;
- @Value("${http.asyncConnectNum}")
- private Integer asyncConnectNum;
- @Value("${http.asyncConnectPerRoute}")
- private Integer asyncConnectPerRoute;
- @Value("${http.asyncIoThreadCount}")
- private Integer asyncIoThreadCount;
- @Value("${http.syncConnectTimeout}")
- private Integer syncConnectTimeout;
- @Value("${http.syncSocketTimeout}")
- private Integer syncSocketTimeout;
- @Value("${http.syncConnectionRequestTimeout}")
- private Integer syncConnectionRequestTimeout;
- @Value("${http.syncConnectPerRoute}")
- private Integer syncConnectPerRoute;
- @Value("${http.syncConnectNum}")
- private Integer syncConnectNum;
- private RequestConfig asyncRequestConfig;
- private PoolingNHttpClientConnectionManager asyncConnManager;
- private RequestConfig syncRequestConfig;
- private PoolingHttpClientConnectionManager syncConnManager;
- private HttpRequestRetryHandler httpRequestRetryHandler;
- @PostConstruct
- public void init() {
- asyncRequestConfig = RequestConfig.custom()
- .setConnectionRequestTimeout(asyncConnectionRequestTimeout)
- .setConnectTimeout(asyncConnectTimeout)
- .setSocketTimeout(asyncSocketTimeout)
- .build();
- //配置io线程
- IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
- .setIoThreadCount(asyncIoThreadCount)
- .setSoKeepAlive(true)
- .build();
- ConnectingIOReactor ioReactor = null;
- try {
- ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);
- } catch (IOReactorException e) {
- logger.error("配置 io 线程失败,error:{}", e.getMessage());
- e.printStackTrace();
- }
- asyncConnManager = new PoolingNHttpClientConnectionManager(ioReactor);
- asyncConnManager.setMaxTotal(asyncConnectNum);
- asyncConnManager.setDefaultMaxPerRoute(asyncConnectPerRoute);
- syncRequestConfig = RequestConfig.custom()
- .setConnectionRequestTimeout(syncConnectionRequestTimeout)
- .setConnectTimeout(syncConnectTimeout)
- .setSocketTimeout(syncSocketTimeout)
- .build();
- syncConnManager = new PoolingHttpClientConnectionManager();
- syncConnManager.setDefaultMaxPerRoute(syncConnectPerRoute);
- syncConnManager.setMaxTotal(syncConnectNum);
- // 请求重试处理
- httpRequestRetryHandler = new HttpRequestRetryHandler() {
- public boolean retryRequest(IOException exception,
- int executionCount, HttpContext context) {
- logger.info("http request occurs error:{}", exception.getMessage());
- if (executionCount >= 3000) {// 如果已经重试了3000次,就放弃
- return false;
- }
- if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
- return false;
- }
- if (exception instanceof SSLException) {// SSL握手异常
- return false;
- }
- if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
- return true;
- }
- if (exception instanceof InterruptedIOException) {// 超时
- return true;
- }
- if (exception instanceof SocketException) {
- return true;
- }
- HttpClientContext clientContext = HttpClientContext
- .adapt(context);
- HttpRequest request = clientContext.getRequest();
- // 如果请求是幂等的,就再次尝试
- if (!(request instanceof HttpEntityEnclosingRequest)) {
- return true;
- }
- return true;
- }
- };
- }
- /**
- * 异步 http 连接
- * @return
- */
- public CloseableHttpAsyncClient getHttpAsyncClient() {
- CloseableHttpAsyncClient client = HttpAsyncClients.custom()
- .setConnectionManager(asyncConnManager)
- .setDefaultRequestConfig(asyncRequestConfig)
- .build();
- return client;
- }
- /**
- * 同步 http 连接
- * @return
- */
- public CloseableHttpClient getHttpSyncClient() {
- CloseableHttpClient httpClient = HttpClients.custom()
- .setConnectionManager(syncConnManager)
- .setDefaultRequestConfig(syncRequestConfig)
- .setRetryHandler(httpRequestRetryHandler)
- .build();
- return httpClient;
- }
- }
|