【问题标题】:Apache HTTPClient does not make more than 2 connectionsApache HTTPClient 不建立超过 2 个连接
【发布时间】:2011-10-07 06:02:18
【问题描述】:

我一直在尝试使用 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);
}

此函数返回的客户端在由ThreadPoolExecutor 管理的Runnables 中使用。 Runnables 使用客户端,并具有以下几行:

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

据我所知,EntityUtils.consume(entity) 将通知连接管理器该连接不再使用,因此将释放该连接以供其他线程使用。所以我猜连接管理没问题。

我想我已经提供了足够的信息,请告诉我是否要添加更多信息。

谢谢

【问题讨论】:

  • 解决 HttpClient 问题的最佳方法是打开其线路/上下文日志记录。按照日志指南hc.apache.org/httpcomponents-client-ga/logging.html 的说明,激活上下文日志以进行连接管理/请求执行。这将帮助您查看每个路由连接池的个人统计信息,还将帮助您查看连接是否正确释放回连接管理器。
  • @oleg 这可能仍然是一个问题吗?看起来修复是任意的,并且 shyam 总结说“我认为这可能是 HttpClient 4.1 API 中的一些错误。”。我看到了类似的问题,不想摇晃代码。
  • 没有什么需要修复的。需要配置连接池以允许每条路由超过 2 个并发连接。

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


【解决方案1】:

好的。我找到了解决方案,感谢oleg 指出了日志记录,以及谷歌和所有论坛。
我所要做的就是只使用连接管理器定义类,然后使用 HttpClient 设置 HttpParams .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 中的某种错误。

【讨论】:

    【解决方案2】:

    我无法在厘米中设置此选项

    cm.setDefaultMaxPerRoute(maxConnections);
    

    有必要这样做:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-10
      • 2016-04-10
      • 2023-03-06
      • 1970-01-01
      • 2016-10-24
      • 2021-02-28
      • 1970-01-01
      相关资源
      最近更新 更多