HttpPoolClientUtil.java 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. package com.tzld.piaoquan.featurestools.util;
  2. import com.google.common.collect.Lists;
  3. import org.apache.commons.lang3.StringUtils;
  4. import org.apache.commons.lang3.concurrent.BasicThreadFactory;
  5. import org.apache.http.HttpEntity;
  6. import org.apache.http.HttpRequestInterceptor;
  7. import org.apache.http.HttpStatus;
  8. import org.apache.http.client.config.RequestConfig;
  9. import org.apache.http.client.methods.*;
  10. import org.apache.http.config.Registry;
  11. import org.apache.http.config.RegistryBuilder;
  12. import org.apache.http.conn.HttpClientConnectionManager;
  13. import org.apache.http.conn.socket.ConnectionSocketFactory;
  14. import org.apache.http.conn.socket.PlainConnectionSocketFactory;
  15. import org.apache.http.conn.ssl.NoopHostnameVerifier;
  16. import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
  17. import org.apache.http.entity.StringEntity;
  18. import org.apache.http.entity.mime.MultipartEntityBuilder;
  19. import org.apache.http.impl.client.CloseableHttpClient;
  20. import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
  21. import org.apache.http.impl.client.HttpClientBuilder;
  22. import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
  23. import org.apache.http.ssl.SSLContexts;
  24. import org.apache.http.util.EntityUtils;
  25. import org.slf4j.Logger;
  26. import org.slf4j.LoggerFactory;
  27. import org.slf4j.MDC;
  28. import javax.net.ssl.SSLContext;
  29. import java.io.File;
  30. import java.io.IOException;
  31. import java.net.SocketTimeoutException;
  32. import java.nio.charset.StandardCharsets;
  33. import java.security.KeyManagementException;
  34. import java.security.KeyStoreException;
  35. import java.security.NoSuchAlgorithmException;
  36. import java.util.List;
  37. import java.util.concurrent.ScheduledExecutorService;
  38. import java.util.concurrent.ScheduledThreadPoolExecutor;
  39. import java.util.concurrent.TimeUnit;
  40. /**
  41. * http client
  42. *
  43. * @author xueyiming
  44. */
  45. public class HttpPoolClientUtil {
  46. private static final Logger LOGGER = LoggerFactory.getLogger(HttpPoolClientUtil.class);
  47. private static final ScheduledExecutorService SCHEDULED_CLOSED_EXECUTOR = new ScheduledThreadPoolExecutor(1,
  48. new BasicThreadFactory.Builder().namingPattern("http conn-closed-thread-%s").priority(Thread.NORM_PRIORITY).daemon(false).build(), (r, e) -> LOGGER.error(" monitor push reject task error={}", e.toString()));
  49. private static final List<HttpClientConnectionManager> HTTP_CLIENT_CONNECTION_MANAGERS = Lists.newArrayList();
  50. static {
  51. SCHEDULED_CLOSED_EXECUTOR.schedule(() -> HTTP_CLIENT_CONNECTION_MANAGERS.forEach(HttpClientConnectionManager::closeExpiredConnections), 5, TimeUnit.SECONDS);
  52. }
  53. private CloseableHttpClient closeableHttpClient;
  54. private HttpPoolClientUtil(CloseableHttpClient closeableHttpClient) {
  55. this.closeableHttpClient = closeableHttpClient;
  56. }
  57. private static HttpRequestInterceptor getInterceptor() {
  58. HttpRequestInterceptor requestInterceptor = (request, context) -> {
  59. try {
  60. String missSpanId = MDC.get("missSpanId");
  61. String missTraceId = MDC.get("request-id");
  62. if (missTraceId != null && !"".equals(missTraceId.trim())) {
  63. request.setHeader("request-id", missTraceId);
  64. }
  65. if (missSpanId != null && !"".equals(missSpanId.trim())) {
  66. request.setHeader("missSpanId", missSpanId);
  67. }
  68. } catch (Exception e) {
  69. LOGGER.error(e.getMessage(), e);
  70. }
  71. };
  72. return requestInterceptor;
  73. }
  74. public String get(String url) throws IOException {
  75. HttpGet httpGet = new HttpGet(url);
  76. return request(httpGet);
  77. }
  78. public String post(String url) throws IOException {
  79. HttpPost httpPost = new HttpPost(url);
  80. return request(httpPost);
  81. }
  82. public String post(String url, String json) throws IOException {
  83. HttpPost httpPost = new HttpPost(url);
  84. if (StringUtils.isBlank(json)) {
  85. return request(httpPost);
  86. }
  87. StringEntity entity = new StringEntity(json, StandardCharsets.UTF_8);
  88. entity.setContentEncoding("UTF-8");
  89. entity.setContentType("application/json");
  90. httpPost.setEntity(entity);
  91. return request(httpPost);
  92. }
  93. public String post(String url, File file) throws IOException {
  94. HttpPost uploadFile = new HttpPost(url);
  95. MultipartEntityBuilder builder = MultipartEntityBuilder.create();
  96. builder.addBinaryBody("media", file);
  97. uploadFile.setEntity(builder.build());
  98. return request(uploadFile);
  99. }
  100. public String request(HttpRequestBase request) throws IOException {
  101. if (LOGGER.isDebugEnabled()) {
  102. String path = request.getURI().toString();
  103. LOGGER.debug("http request url = {} ", path);
  104. }
  105. HttpEntity entity = null;
  106. CloseableHttpResponse response = request((HttpUriRequest) request);
  107. if (response == null) {
  108. throw new RuntimeException("call api exception no response");
  109. }
  110. entity = response.getEntity();
  111. String content = null;
  112. if (entity != null) {
  113. content = EntityUtils.toString(entity, "UTF-8");
  114. }
  115. int httpStatus = response.getStatusLine().getStatusCode();
  116. if (httpStatus == HttpStatus.SC_OK) {
  117. return content;
  118. }
  119. String path = request.getURI().toString();
  120. LOGGER.error("http call api {} fail response status {} content {}", path, httpStatus, content);
  121. // throw new HttpServiceException(httpStatus, content);
  122. return null;
  123. }
  124. public CloseableHttpResponse request(HttpUriRequest request) {
  125. try {
  126. CloseableHttpResponse execute = closeableHttpClient.execute(request);
  127. return execute;
  128. } catch (Exception e) {
  129. String path = request.getURI().toString();
  130. if (e instanceof SocketTimeoutException) {
  131. LOGGER.error(String.format("http timeout request url = %s .", path));
  132. // throw new TimeoutException();
  133. } else {
  134. }
  135. throw new RuntimeException(String.format("http exception request url = %s ", path), e);
  136. }
  137. }
  138. /**
  139. * @param connectTimeout 连接超时时间 ms
  140. * @param socketTimeout 读超时时间(等待数据超时时间)ms
  141. * @param maxPerRoute 每个路由的最大连接数
  142. * @param maxTotal 最大连接数
  143. * @param retryCount 重试次数
  144. * @return httpclient instance
  145. */
  146. public static HttpPoolClientUtil create(int connectTimeout, int socketTimeout, int maxPerRoute, int maxTotal, int retryCount, int connectionWaitTimeout) {
  147. try {
  148. RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).setConnectionRequestTimeout(connectionWaitTimeout).build();
  149. CloseableHttpClient client = HttpClientBuilder.create()
  150. .setDefaultRequestConfig(requestConfig)
  151. .setConnectionManager(createConnectionManager(maxPerRoute, maxTotal))
  152. .setRetryHandler(new DefaultHttpRequestRetryHandler(retryCount, false)).addInterceptorFirst(getInterceptor()).build();
  153. return new HttpPoolClientUtil(client);
  154. } catch (Throwable e) {
  155. LOGGER.error("create HttpPoolClient exception", e);
  156. throw new RuntimeException("create HttpPoolClient exception");
  157. }
  158. }
  159. private static PoolingHttpClientConnectionManager createConnectionManager(int maxPerRoute, int maxTotal) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException {
  160. SSLContext sslContext = SSLContexts.custom().loadTrustMaterial((chain, authType) -> true).build();
  161. Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
  162. .register("http", PlainConnectionSocketFactory.getSocketFactory())
  163. .register("https", new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE)).build();
  164. PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
  165. cm.setDefaultMaxPerRoute(maxPerRoute);
  166. cm.setMaxTotal(maxTotal);
  167. HTTP_CLIENT_CONNECTION_MANAGERS.add(cm);
  168. return cm;
  169. }
  170. }