I have following http client code(HttpUtils and HttpClientManager)with HttpClient 4.3.6, and a httpclient code in 3.1, and a test case as well. I observed that HttpClient 4.3.6 is very much slowly than HttpClient 3.1 code. In HttpClient 4.3.6 version code, there are a lot socket time out error(the socket time is 10 seconds).
I pasted the related classes and code below. It is kind of long code, but I still would ask you do me a favor to review the http client configuration that may cause the problem. Many Thanks in advance. Following codes include: 1. HttpClient 4.3.6 code to issue HttpGet request 2. HttpClient 3.1 code to issue HttpGet request 3. Test Case that demontrate the problem. ############################################Http Client 4.3.6 Code goes here############################################ ///////////////////////////HttpUtils////////////////////////////////////////// import java.util.ArrayList; import java.util.List; import java.util.Map; import org.apache.http.Consts; import org.apache.http.NameValuePair; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.message.BasicNameValuePair; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HttpUtils { ///This is the util method that will be used to issue http request. public static String httpInvoke(String httpUrl, Map<String, Object> parameters, RequestConfig config){ HttpClientManager httpClientConnectionManager = HttpClientManager.getHttpClientConnectionManagerInstance(); HttpGet httpGet = new HttpGet(httpUrl); if(config != null ){ httpGet.setConfig(config); } String result = httpClientConnectionManager.execute(httpGet); return result; } } //////////////////////////////////HttpClientManager///////////////////////////////// import java.nio.charset.CodingErrorAction; import java.util.ArrayList; import java.util.Collection; import org.apache.commons.httpclient.Header; import org.apache.commons.httpclient.HttpStatus; import org.apache.commons.lang3.StringUtils; import org.apache.http.Consts; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.GzipDecompressingEntity; 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.config.ConnectionConfig; import org.apache.http.config.MessageConstraints; import org.apache.http.config.SocketConfig; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicHeader; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; ///Main class that encapsulate the Http Client public class HttpClientManager { private static Logger logger = LoggerFactory.getLogger(HttpClientManager.class); private static int defaultConnectionTimeout = 10*1000; //connection timeout private static int defaultSocketTimeout = 10*1000; //socket time out private static int connectionRequestTimeout = 10*1000; //connection request timeout private static int defaultMaxRouteConnections = 128; private static int defaultMaxTotalConnections = 1024; private static int defaultMaxHeaderCount = 200; private static int defaultMaxLineLength = 2000; private static String Charset = "utf-8"; private String proxyHost = null; private String proxyPort =null; private PoolingHttpClientConnectionManager cm; private final static HttpClientManager httpClientConnectionManager = new HttpClientManager(); private HttpClientManager() { logger.info("HttpClientManager initial!"); cm = new PoolingHttpClientConnectionManager(); cm.setMaxTotal(defaultMaxTotalConnections); cm.setDefaultMaxPerRoute(defaultMaxRouteConnections); } private CloseableHttpClient getHttpclient(){ HttpClientBuilder httpClientBuilder = HttpClients.custom(); httpClientBuilder.setConnectionManager(cm); RequestConfig.Builder requestConfigBuilder = RequestConfig.custom() .setConnectTimeout(defaultConnectionTimeout) .setSocketTimeout(defaultSocketTimeout) .setConnectionRequestTimeout(connectionRequestTimeout) .setExpectContinueEnabled(false) .setStaleConnectionCheckEnabled(true); if(StringUtils.isNotBlank(proxyHost) && StringUtils.isNotBlank(proxyPort)){ try{ logger.info("using proxy, proxyHost:{}, proxyPort:{}", proxyHost, proxyPort); int proxyPortInt = Integer.parseInt(proxyPort); requestConfigBuilder.setProxy(new HttpHost(proxyHost, proxyPortInt)); } catch(Exception e){ logger.error("parseInt proxyPort:{}", proxyPort, e); } } SocketConfig socketConfig = SocketConfig.custom().setTcpNoDelay(true).build(); MessageConstraints messageConstraints = MessageConstraints.custom().setMaxHeaderCount(defaultMaxHeaderCount).setMaxLineLength(defaultMaxLineLength).build(); ConnectionConfig connectionConfig = ConnectionConfig.custom() .setMalformedInputAction(CodingErrorAction.IGNORE) .setUnmappableInputAction(CodingErrorAction.IGNORE) .setCharset(Consts.UTF_8) .setMessageConstraints(messageConstraints).build(); Collection<BasicHeader> collection = new ArrayList<BasicHeader>(); collection.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3")); collection.add(new BasicHeader("Accept-Language", "zh-cn,zh,en-US,en;q=0.5")); collection.add(new BasicHeader("Accept-Charset", Charset)); collection.add(new BasicHeader("Accept-Encoding", "gzip")); httpClientBuilder.setDefaultRequestConfig(requestConfigBuilder.build()); httpClientBuilder.setDefaultSocketConfig(socketConfig); httpClientBuilder.setDefaultConnectionConfig(connectionConfig); httpClientBuilder.setDefaultHeaders(collection); return httpClientBuilder.build(); } ///This is the method that will be call the execute the HttpGet request public String execute(HttpGet httpGet) { String body = ""; try{ CloseableHttpClient httpclient = this.getHttpclient(); CloseableHttpResponse response = httpclient.execute(httpGet); int status = response.getStatusLine().getStatusCode(); try { if (status == HttpStatus.SC_OK) { HttpEntity entity = response.getEntity(); if (entity != null) { Header header = (Header) entity.getContentEncoding(); if(header != null && "gzip".equals(header.getValue())){ body = EntityUtils.toString(new GzipDecompressingEntity(entity), Charset); } else { body = EntityUtils.toString(entity, Charset); } } } else { logger.error("[httpClientManager] [fail] [httpGet:{}] [status:{}]", httpGet, status); } } finally { response.close(); } } catch(Exception e) { logger.error("[module:httpClientManager] [action:execute] [httpGet:{}] [error:{}] ", httpGet, e.getMessage(), e); } return body; } ////Singleton object that will be used to access httpClientConnectionManager public static HttpClientManager getHttpClientConnectionManagerInstance(){ return httpClientConnectionManager; } } ##################################################My HttpClient 1.3 code goes here########################################### import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.methods.GetMethod; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; public class HttpClientUtil { private static final HttpClientUtil INSTANCE = new HttpClientUtil(); private static final int TIMEOUT = 10 * 1000; //10s private HttpClientUtil() { } ///Actually, this class is more like a static class than Singleton public static HttpClientUtil getInstance() { return INSTANCE; } //brand new http client per request private HttpClient newHttpClient() { HttpClient client = new HttpClient(); client.getHttpConnectionManager().getParams().setConnectionTimeout(TIMEOUT); client.getHttpConnectionManager().getParams().setSoTimeout(TIMEOUT); return client; } //FIXME The encoding should be provided when convert the response binary stream into string public static String responseBodyAsString(HttpMethod method) throws IOException { BufferedReader br = null; String lsr = System.getProperty("line.separator"); try { InputStream in = method.getResponseBodyAsStream(); br = new BufferedReader(new InputStreamReader(in, "UTF-8")); StringBuffer sb = new StringBuffer(); String line; while ((line = br.readLine()) != null) { sb.append(line).append(lsr); } return sb.toString(); } finally { if (br != null) { br.close(); } } } /////This is the method that will HttpGet to the url public String get(String url) throws IOException { GetMethod pm = new GetMethod(url); pm.setRequestHeader("Connection", "close"); HttpClient client = newHttpClient(); try { client.executeMethod(pm); String response = responseBodyAsString(pm); return response; } finally { pm.releaseConnection(); } } } ##########################################Test Case########################################## The following code runs in the one thread in the junit test while (i++ < 5000) { long start = System.currentTimeMillis(); HttpUtils.httpInvoke(TEST_URL, null, null); long a = System.currentTimeMillis() - start; String timeSpent = "" + (a >= 1000 ? a + "(>1000)" : a); writeToFile(timeSpent + "\n", logFile); Thread.sleep(loopInterval); } bit1...@163.com