java高并发连接池_Java httpClient 使用连接池支持多线程高并发

当使用HttpClient默认方式创建实例时,可能导致'Address already in use'异常。通过引入连接池解决这个问题,确保资源有效管理和释放。示例代码展示了如何配置PoolingHttpClientConnectionManager和HttpRequestRetryHandler以创建支持高并发的HttpClient。
摘要由CSDN通过智能技术生成

当采用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 buildResultMap(CloseableHttpResponse response, HttpEntity entity) throws

IOException {

Map 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 postJson(String url, String message) {

Map 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;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值