HttpClientSpringFactory.java 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. package com.uas.ps.inquiry.http;
  2. import org.apache.http.HttpEntityEnclosingRequest;
  3. import org.apache.http.HttpRequest;
  4. import org.apache.http.NoHttpResponseException;
  5. import org.apache.http.client.HttpRequestRetryHandler;
  6. import org.apache.http.client.config.RequestConfig;
  7. import org.apache.http.client.protocol.HttpClientContext;
  8. import org.apache.http.impl.client.CloseableHttpClient;
  9. import org.apache.http.impl.client.HttpClients;
  10. import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
  11. import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
  12. import org.apache.http.impl.nio.client.HttpAsyncClients;
  13. import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
  14. import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
  15. import org.apache.http.impl.nio.reactor.IOReactorConfig;
  16. import org.apache.http.nio.reactor.ConnectingIOReactor;
  17. import org.apache.http.nio.reactor.IOReactorException;
  18. import org.apache.http.protocol.HttpContext;
  19. import org.slf4j.Logger;
  20. import org.slf4j.LoggerFactory;
  21. import org.springframework.beans.factory.annotation.Value;
  22. import org.springframework.stereotype.Component;
  23. import javax.annotation.PostConstruct;
  24. import javax.net.ssl.SSLException;
  25. import javax.net.ssl.SSLHandshakeException;
  26. import java.io.IOException;
  27. import java.io.InterruptedIOException;
  28. import java.net.SocketException;
  29. /**
  30. * http 同步连接池、http 异步连接池,与spring集成
  31. * @author liuam
  32. * @since 2018/8/27 0027 下午 15:58
  33. */
  34. @Component
  35. public class HttpClientSpringFactory {
  36. private static final Logger logger = LoggerFactory.getLogger(HttpClientSpringFactory.class);
  37. @Value("${http.asyncConnectTimeout}")
  38. private Integer asyncConnectTimeout;
  39. @Value("${http.asyncSocketTimeout}")
  40. private Integer asyncSocketTimeout;
  41. @Value("${http.asyncConnectionRequestTimeout}")
  42. private Integer asyncConnectionRequestTimeout;
  43. @Value("${http.asyncConnectNum}")
  44. private Integer asyncConnectNum;
  45. @Value("${http.asyncConnectPerRoute}")
  46. private Integer asyncConnectPerRoute;
  47. @Value("${http.asyncIoThreadCount}")
  48. private Integer asyncIoThreadCount;
  49. @Value("${http.syncConnectTimeout}")
  50. private Integer syncConnectTimeout;
  51. @Value("${http.syncSocketTimeout}")
  52. private Integer syncSocketTimeout;
  53. @Value("${http.syncConnectionRequestTimeout}")
  54. private Integer syncConnectionRequestTimeout;
  55. @Value("${http.syncConnectPerRoute}")
  56. private Integer syncConnectPerRoute;
  57. @Value("${http.syncConnectNum}")
  58. private Integer syncConnectNum;
  59. private RequestConfig asyncRequestConfig;
  60. private PoolingNHttpClientConnectionManager asyncConnManager;
  61. private RequestConfig syncRequestConfig;
  62. private PoolingHttpClientConnectionManager syncConnManager;
  63. private HttpRequestRetryHandler httpRequestRetryHandler;
  64. @PostConstruct
  65. public void init() {
  66. asyncRequestConfig = RequestConfig.custom()
  67. .setConnectionRequestTimeout(asyncConnectionRequestTimeout)
  68. .setConnectTimeout(asyncConnectTimeout)
  69. .setSocketTimeout(asyncSocketTimeout)
  70. .build();
  71. //配置io线程
  72. IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
  73. .setIoThreadCount(asyncIoThreadCount)
  74. .setSoKeepAlive(true)
  75. .build();
  76. ConnectingIOReactor ioReactor = null;
  77. try {
  78. ioReactor = new DefaultConnectingIOReactor(ioReactorConfig);
  79. } catch (IOReactorException e) {
  80. logger.error("配置 io 线程失败,error:{}", e.getMessage());
  81. e.printStackTrace();
  82. }
  83. asyncConnManager = new PoolingNHttpClientConnectionManager(ioReactor);
  84. asyncConnManager.setMaxTotal(asyncConnectNum);
  85. asyncConnManager.setDefaultMaxPerRoute(asyncConnectPerRoute);
  86. syncRequestConfig = RequestConfig.custom()
  87. .setConnectionRequestTimeout(syncConnectionRequestTimeout)
  88. .setConnectTimeout(syncConnectTimeout)
  89. .setSocketTimeout(syncSocketTimeout)
  90. .build();
  91. syncConnManager = new PoolingHttpClientConnectionManager();
  92. syncConnManager.setDefaultMaxPerRoute(syncConnectPerRoute);
  93. syncConnManager.setMaxTotal(syncConnectNum);
  94. // 请求重试处理
  95. httpRequestRetryHandler = new HttpRequestRetryHandler() {
  96. public boolean retryRequest(IOException exception,
  97. int executionCount, HttpContext context) {
  98. logger.info("http request occurs error:{}", exception.getMessage());
  99. if (executionCount >= 3000) {// 如果已经重试了3000次,就放弃
  100. return false;
  101. }
  102. if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
  103. return false;
  104. }
  105. if (exception instanceof SSLException) {// SSL握手异常
  106. return false;
  107. }
  108. if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接,那么就重试
  109. return true;
  110. }
  111. if (exception instanceof InterruptedIOException) {// 超时
  112. return true;
  113. }
  114. if (exception instanceof SocketException) {
  115. return true;
  116. }
  117. HttpClientContext clientContext = HttpClientContext
  118. .adapt(context);
  119. HttpRequest request = clientContext.getRequest();
  120. // 如果请求是幂等的,就再次尝试
  121. if (!(request instanceof HttpEntityEnclosingRequest)) {
  122. return true;
  123. }
  124. return true;
  125. }
  126. };
  127. }
  128. /**
  129. * 异步 http 连接
  130. * @return
  131. */
  132. public CloseableHttpAsyncClient getHttpAsyncClient() {
  133. CloseableHttpAsyncClient client = HttpAsyncClients.custom()
  134. .setConnectionManager(asyncConnManager)
  135. .setDefaultRequestConfig(asyncRequestConfig)
  136. .build();
  137. return client;
  138. }
  139. /**
  140. * 同步 http 连接
  141. * @return
  142. */
  143. public CloseableHttpClient getHttpSyncClient() {
  144. CloseableHttpClient httpClient = HttpClients.custom()
  145. .setConnectionManager(syncConnManager)
  146. .setDefaultRequestConfig(syncRequestConfig)
  147. .setRetryHandler(httpRequestRetryHandler)
  148. .build();
  149. return httpClient;
  150. }
  151. }