Thanks Alexey for the apply。 I tried it, and sorry that it still doesn't work. 
I am using one thread to sending http request for 1000 times every 20 
milliseconds. Some response time are as follows:
As you can see, the response time is not stable at all, (there are ocurrences 
with 7~10 seconds). If I don't use pool connection manager, then the response 
time are very stable, about 200 milliseconds for each request.

Is there code example that issuing HTTP request with pool connection manager 
and apply the best practices for the CloseableHttpClient/response release/close 
or related things. So that, I can compare it with mine, and hopefully find 
whether  the problem is.
Thanks.

My testing code snippet:

public void test() {
        long allStart = System.currentTimeMillis(); 
while (i++ < loop) { 
long start = System.currentTimeMillis(); 
HttpUtils.httpInvoke(TEST_URL, null, null);  //This the core code that issuing 
http request.
long a = System.currentTimeMillis() - start; 
String timeSpent = "" + (a >= 1000 ? a + "(>1000)" : a); 
writeToFile(timeSpent + "\n", logFile); 
Thread.sleep(loopInterval); 
} 
writeToFile("Total time spent: " + (System.currentTimeMillis() - allStart) + 
"\n", logFile);


}

26 
30 
235 
439 
851 
1667 
1040 
234 
439 
851 
1671 
3310 
25 
27 
26 
238 
25 
234 
435 
24 
235 
24 
26 
27 
25 
232 
27 
26 
37 
29 
28 
251 
472 
915 
1804 
3580 
7132 
10057 
28 
26 
253 
26 
25 
23 
243 
24 
24 
27 
26 
1025 
27 
29 
24 
23




bit1...@163.com
 
From: Alexey Panchenko
Date: 2015-07-08 11:42
To: HttpClient User Discussion
Subject: Re: Re: httpclient4 is extremely slow than correpsoning code of 
HttpClient3
AFAIK there is no need in creating a new HttpClient instance every time, it
should be created once and reused.
 
On Wed, Jul 8, 2015 at 9:29 AM, bit1...@163.com <bit1...@163.com> wrote:
 
> One more thing that I noticed is:
>
> When I constructing the CloseableHttpClient, response time gets back to
> normal if I don't pass the PoolingHttpClientConnectionManager object to the
> HttpClientBuilder
>
>   HttpClientBuilder httpClientBuilder = HttpClients.custom();
>
>   /*comment this code so that no PoolingHttpClientConnectionManager will
> be used!*/
>   //httpClientBuilder.setConnectionManager(cm);
>
>   //other configurations
>   return httpClientBuilder.build();
>
> Seems that there are something related with
> PoolingHttpClientConnectionManager that cause the request's response time
> is abnormally long.
>
> Here is my code about PoolingHttpClientConnectionManager :
>
> cm = new PoolingHttpClientConnectionManager();
> cm.setMaxTotal(1024);
> cm.setDefaultMaxPerRoute(128);
>
>
>
> bit1...@163.com
>
> From: bit1...@163.com
> Date: 2015-07-08 10:25
> To: httpclient-users
> Subject: Re: Re: httpclient4 is extremely slow than correpsoning code of
> HttpClient3
> Thanks Stefan for the reply.
>
> Do you mean that I move the CloseableHttpClient out of the try block like
> following,
>
> public String execute(HttpGet httpGet) {
> String body = "";
> CloseableHttpClient httpclient = this.getHttpclient();
> try{
> CloseableHttpResponse response = httpclient.execute(httpGet);
> int status = response.getStatusLine().getStatusCode();
> ///other codes goes for consuming response
>
> Unfortunately, It still doesn't work for me, and I still see that the
> request time is abnormally long.
>
> One thing I notice, is that when I set the socket time out to be 10
> seconds, there are couple of requests throw exception due to socket time
> out. So I wonder what may cause socket time out issue. With httpclient3, I
> see no such problems, and the longest request time is no more that 2
> seconds.
>
>
>
>
>
>
> bit1...@163.com
> From: Stefan Magnus Landrø
> Date: 2015-07-08 00:33
> To: HttpClient User Discussion
> Subject: Re: httpclient4 is extremely slow than correpsoning code of
> HttpClient3
> >> try{
> >> CloseableHttpClient httpclient =
> Try with resources will close client
> Sendt fra min iPhone
> > Den 7. jul. 2015 kl. 16.59 skrev Todd <bit1...@163.com>:
> >
> > Thanks Stefan for the reply. Could you please point to me which code you
> are referring to?
> >
> >
> >
> > At 2015-07-07 22:49:28, "Stefan Magnus Landrø" <stefan.lan...@gmail.com>
> wrote:
> >> You shouldn't close http client on every request, only response
> >>
> >> Sendt fra min iPhone
> >>
> >>> Den 7. jul. 2015 kl. 16.05 skrev "bit1...@163.com" <bit1...@163.com>:
> >>>
> >>>
> >>> Can someone kindly help me on this? Thanks a lot!
> >>>
> >>>
> >>>
> >>>
> >>> bit1...@163.com
> >>>
> >>> From: bit1...@163.com
> >>> Date: 2015-07-07 20:51
> >>> To: httpclient-users
> >>> Subject: httpclient4 is extremely slow than correpsoning code of
> HttpClient3
> >>>
> >>> 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
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: httpclient-users-unsubscr...@hc.apache.org
> >> For additional commands, e-mail: httpclient-users-h...@hc.apache.org
> >>
>

Reply via email to