Apache HTTPClient不会超过2个连接

时间:2011-10-07 06:02:18

标签: java httpconnection apache-httpclient-4.x

我一直在尝试使用Apache HTTPClient(v4.1)为我的应用程序实现连接池。问题是客户端在运行时总是只创建两个连接,尽管有足够的线程并行运行。我一直试图修改代码一段时间,但是没有任何帮助 我正在使用ThreadSafeClientConnManager进行连接池,并将MaxTotalDefaulMaxPerRoute设置为我想要的值。
首先我想到的是你想要检查的东西吗?

这是我用来创建客户端的代码段。

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, PlainSocketFactory.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);
}

此功能返回的客户端由Runnables管理的ThreadPoolExecutor使用。 Runnables使用客户端,并具有以下行:

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

据我所知,EntityUtils.consume(entity)将通知连接管理器该连接已不再使用,因此将释放其他线程使用的连接。所以我猜测连接管理没问题
我想我已经提供了足够的信息,请告诉我是否要添加更多信息
感谢

2 个答案:

答案 0 :(得分:7)

行。我找到了解决方案,感谢oleg指出日志记录,以及google和所有论坛。
我所要做的就是只用连接管理器定义类,然后设置HttpParams使用HttpClient.setParams()。所以代码看起来像这样:

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);
}

在使用客户端之前,

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

代码逻辑显然没有区别,但这解决了我的问题。我认为这可能是HttpClient 4.1 API中的一些错误。

答案 1 :(得分:0)

我无法在cm

中设置此选项
cm.setDefaultMaxPerRoute(maxConnections);

有必要这样做:

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