开发者

Apache HTTPClient does not make more than 2 connections

开发者 https://www.devze.com 2023-04-11 03:28 出处:网络
I\'ve been trying to implement connection pooling for my application using Apache HTTPClient (v4.1). The problem is that the client always makes only two connections when run, though there are enough

I've been trying to implement connection pooling for my application using Apache HTTPClient (v4.1). The problem is that the client always makes only two connections when run, though there are enough threads running parallel. I have been trying to modify the code for a while now, but nothing has helped yet.

I'm using ThreadSafeClientConnManager for connection pooling and set the MaxTotal and DefaulMaxPerRoute to values I want.

Is there anything that comes to your mind first that I might want to check?


Here's that code segment that I use to create the client.

DefaultHttpClient createClient() {
    HttpParams params = new BasicHttpParams();
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

    params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, new Integer(60000));
    params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, new Integer(60000));
    params.setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true);

    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("https", sf, 6443));
    registry.register(new Scheme("http", 80, PlainSock开发者_高级运维etFactory.getSocketFactory()));

    ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params, registry);
    cm.setMaxTotal(2 * maxConnections);
    cm.setDefaultMaxPerRoute(maxConnections);

    HttpHost localhost = new HttpHost("localhost");
    cm.setMaxForRoute(new HttpRoute(localhost), maxConnections);

    HttpHost sdpTargetHost = new HttpHost("webserviceIP", webservicePort, "https");
    cm.setMaxForRoute(new HttpRoute(sdpTargetHost, null, true), maxConnections);

    return new DefaultHttpClient(cm, params);
}

The client returned by this function is used in Runnables managed by a ThreadPoolExecutor. The Runnables use the client, and has these lines:

HttpResponse response = httpClient.execute(httpPost, context);
HttpEntity entity = response.getEntity();
....
EntityUtils.consume(entity);

From what I know, the EntityUtils.consume(entity) will notify the connection manager that the connection is no longer used, and thus will release the connection to be used by other threads. So I'm guessing the connection management is alright.

I guess I've provided enough info, please tell me if I'm to add anything more.

Thanks


OK. I've found the solution, thanks to oleg for pointing out the logging, and to google and all the forums.
All I had to do was define the class with only the connection manager, and then set HttpParams using HttpClient.setParams(). So the code will look something like this:

DefaultHttpClient createClient() {
    SchemeRegistry registry = new SchemeRegistry();
    registry.register(new Scheme("https", sf, 6443));

    ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(registry);
    cm.setMaxTotal(maxConnections);
    cm.setDefaultMaxPerRoute(maxConnections);

    HttpHost targetHost = new HttpHost("webserviceIP", webservicePort, "https");
    cm.setMaxForRoute(new HttpRoute(targetHost, null, true), maxConnections);

    return new DefaultHttpClient(cm);
}

And right before using the client,

DefaultHttpClient httpClient = createClient();
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, new Integer(60000));
params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, new Integer(60000));
params.setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true);
httpClient.setParams(params);

There apparently is no difference in the code logically, but this fixed my problem. I presume this probably is some sorta bug in the HttpClient 4.1 API.


I was not able to set this option in cm

cm.setDefaultMaxPerRoute(maxConnections);

It was necessary to do so:

ConnPerRoute perRoute = new ConnPerRouteBean(100);
ConnManagerParams.setMaxConnectionsPerRoute(params, perRoute);
ConnManagerParams.setMaxTotalConnections(params, 100);
ConnManagerParams.setTimeout(params, 15000);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号