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

 更新时间:2021年08月24日 10:34:42   作者:qzqanlhy1314  
本文主要介绍了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连接池多线程高并发内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解读Hibernate、MyBatis有哪些区别

    解读Hibernate、MyBatis有哪些区别

    Hibernate和MyBatis是Java中常用的持久层框架,各有优势和适用场景,Hibernate通过对象关系映射简化数据库操作,适合复杂业务逻辑;MyBatis提供更高的SQL控制权,适合需要直接操作SQL的场景,选择应基于项目需求和团队习惯
    2025-01-01
  • Java 内部类的定义与范例

    Java 内部类的定义与范例

    说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉。原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法。今天我们就来一探究竟
    2021-11-11
  • java导出csv方法实现讲解

    java导出csv方法实现讲解

    这篇文章主要介绍了java导出csv的方法,客户要求在项目中有导出CSV文件的功能,并且给出了如何在不知道如何在不知道对象类型(没有应用泛型)的List中如何得到对象的属性值,下面就详细说下这个功能是如何实现的
    2013-12-12
  • Java中的Runnable,Callable,Future,FutureTask的比较

    Java中的Runnable,Callable,Future,FutureTask的比较

    这篇文章主要介绍了Java中的Runnable,Callable,Future,FutureTask的比较的相关资料,需要的朋友可以参考下
    2017-02-02
  • Spring IOC 常用注解与使用实例详解

    Spring IOC 常用注解与使用实例详解

    这篇文章主要介绍了Spring IOC 常用注解与使用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • SpringBoot后端接收参数优化代码示例(统一处理前端参数)

    SpringBoot后端接收参数优化代码示例(统一处理前端参数)

    使用Spring Boot开发API的时候,读取请求参数是服务端编码中最基本的一项操作,下面这篇文章主要给大家介绍了关于SpringBoot后端接收参数优化(统一处理前端参数)的相关资料,需要的朋友可以参考下
    2024-07-07
  • java 实现 stack详解及实例代码

    java 实现 stack详解及实例代码

    这篇文章主要介绍了java 实现 stack详解的相关资料,需要的朋友可以参考下
    2016-09-09
  • SpringBoot 使用@WebMvcTest测试MVC Web Controller

    SpringBoot 使用@WebMvcTest测试MVC Web Controller

    这篇文章主要介绍了SpringBoot 使用@WebMvcTest测试MVC Web Controller,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • 详解Java 缺失的特性扩展方法

    详解Java 缺失的特性扩展方法

    这篇文章主要为大家介绍了Java 缺失的特性扩展方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • 浅析Android系统中HTTPS通信的实现

    浅析Android系统中HTTPS通信的实现

    这篇文章主要介绍了浅析Android系统中HTTPS通信的实现,实现握手的源码为Java语言编写,需要的朋友可以参考下
    2015-07-07

最新评论