当采用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 解决了这个问题,避免资源一直占用不释放的问题。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
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连接池多线程高并发内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
原文链接:https://blog.csdn.net/qzqanzc/article/details/84344655
查看更多关于Java httpClient连接池支持多线程高并发的实现的详细内容...