小蚂蚁 发表于 2021-12-1 19:24:33

Java httpClient连接池支持多线程高并发的实现

本文主要介绍了Java httpClient连接池支持多线程高并发的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
当采用HttpClient httpClient = HttpClients.createDefault() 实例化的时候。会导致Address already in use的异常。

信息: I/O exception (java.net.BindException) caught when processing request to {}->http://**.**.**.** Address already in use: connect
十一月 22, 2018 5:02:13 下午 org.apache.http.impl.execchain.RetryExec execute
信息: Retrying request to {}->http://**.**.**.**
java.net.BindException: Address already in use: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
采用连接池来创建httpClient 解决了这个问题,避免资源一直占用不释放的问题。


import org.apache.http.HttpEntity;
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.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.StringEntity;
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.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;

public class WebTools {

    public static String KEY_STATUS_CODE = "statusCode";
    public static String KEY_CONTENT = "content";

    private final static PoolingHttpClientConnectionManager poolConnManager = new PoolingHttpClientConnectionManager();//连接池管理器
    private final static HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {//retry handler
      public boolean retryRequest(IOException exception,
                                    int executionCount, HttpContext context) {
            if (executionCount >= 5) {
                return false;
            }
            if (exception instanceof NoHttpResponseException) {
                return true;
            }
            if (exception instanceof InterruptedIOException) {
                return false;
            }
            if (exception instanceof UnknownHostException) {
                return false;
            }
            if (exception instanceof ConnectTimeoutException) {
                return false;
            }
            HttpClientContext clientContext = HttpClientContext
                  .adapt(context);
            HttpRequest request = clientContext.getRequest();

            if (!(request instanceof HttpEntityEnclosingRequest)) {
                return true;
            }
            return false;
      }
    };

    static {   //类加载的时候 设置最大连接数 和 每个路由的最大连接数
      poolConnManager.setMaxTotal(2000);
      poolConnManager.setDefaultMaxPerRoute(1000);
    }


    /**
   * ########################### core code#######################
   * @return
   */
    private static CloseableHttpClient getCloseableHttpClient() {
      CloseableHttpClient httpClient = HttpClients.custom()
                .setConnectionManager(poolConnManager)
                .setRetryHandler(httpRequestRetryHandler)
                .build();

      return httpClient;
    }

    /**
   * buildResultMap
   *
   * @param response
   * @param entity
   * @return
   * @throws IOException
   */
    private static Map<String, Object> buildResultMap(CloseableHttpResponse response, HttpEntity entity) throws
            IOException {
      Map<String, Object> result;
      result = new HashMap<>(2);
      result.put(KEY_STATUS_CODE, response.getStatusLine().getStatusCode());//status code
      if (entity != null) {
            result.put(KEY_CONTENT, EntityUtils.toString(entity, "UTF-8")); //message content
      }
      return result;
    }

    /**
   * send json by post method
   *
   * @param url
   * @param message
   * @return
   * @throws Exception
   */
    public static Map<String, Object> postJson(String url, String message) {

      Map<String, Object> result = null;
      CloseableHttpClient httpClient = getCloseableHttpClient();
      HttpPost httpPost = new HttpPost(url);
      CloseableHttpResponse response = null;
      try {

            httpPost.setHeader("Accept", "application/json;charset=UTF-8");
            httpPost.setHeader("Content-Type", "application/json");

            StringEntity stringEntity = new StringEntity(message);
            stringEntity.setContentType("application/json;charset=UTF-8");

            httpPost.setEntity(stringEntity);
            response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            result = buildResultMap(response, entity);

      } catch (Exception e) {
            e.printStackTrace();
      } finally {
            if (response != null) {
                try {
                  EntityUtils.consume(response.getEntity());
                  response.close();
                } catch (IOException e) {
                  e.printStackTrace();
                }
            }
      }
      return result;
    }
}
到此这篇关于Java httpClient连接池支持多线程高并发的实现的文章就介绍到这了,更多相关Java httpClient连接池多线程高并发内容请搜索CodeAE代码之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持CodeAE代码之家!
原文链接:https://blog.csdn.net/qzqanzc/article/details/84344655

http://www.zzvips.com/article/208919.html
页: [1]
查看完整版本: Java httpClient连接池支持多线程高并发的实现