Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Apache HTTPClient建立的连接不超过2个_Java_Httpconnection_Apache Httpclient 4.x - Fatal编程技术网

Java Apache HTTPClient建立的连接不超过2个

Java Apache HTTPClient建立的连接不超过2个,java,httpconnection,apache-httpclient-4.x,Java,Httpconnection,Apache Httpclient 4.x,我一直在尝试使用ApacheHttpClient(v4.1)为我的应用程序实现连接池。问题是,尽管有足够多的线程并行运行,但客户端在运行时总是只进行两个连接。我已经尝试修改代码一段时间了,但是没有任何帮助。 我正在使用ThreadSafeClientConnManager进行连接池,并将MaxTotal和DefaulMaxPerRoute设置为我想要的值。 你有没有先想到什么我想检查的? 这是我用来创建客户机的代码段。 DefaultHttpClient createClient() {

我一直在尝试使用ApacheHttpClient(v4.1)为我的应用程序实现连接池。问题是,尽管有足够多的线程并行运行,但客户端在运行时总是只进行两个连接。我已经尝试修改代码一段时间了,但是没有任何帮助。
我正在使用
ThreadSafeClientConnManager
进行连接池,并将
MaxTotal
DefaulMaxPerRoute
设置为我想要的值。
你有没有先想到什么我想检查的?

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

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
中。可运行程序使用客户端,并具有以下行:

HttpResponse response = httpClient.execute(httpPost, context);
HttpEntity entity = response.getEntity();
....
EntityUtils.consume(entity);
据我所知,
EntityUtils.consume(entity)
将通知连接管理器不再使用该连接,从而释放该连接供其他线程使用。所以我猜连接管理是正常的。

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


谢谢

好的。我已经找到了解决方案,感谢您指出日志记录,感谢google和所有论坛。
我所要做的就是只使用连接管理器定义类,然后使用HttpClient.setParams()设置HttpParams。因此,代码将如下所示:

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中的一些错误。

我无法在cm中设置此选项

cm.setDefaultMaxPerRoute(maxConnections);
有必要这样做:

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

也许是相同的:解决HttpClient问题的最佳方法是打开其wire/context日志记录。按照《日志记录指南》中的说明,激活连接管理/请求执行的上下文日志记录。这将帮助您查看每个路由连接池的统计信息,并帮助您查看连接是否正确释放回连接管理器。@oleg这可能仍然是个问题吗?似乎修复是任意的,shyam总结道:“我想这可能是HttpClient 4.1 API中的一些小错误。”。我看到了一个类似的问题,不想修改代码。没有什么需要修复的。需要将连接池配置为每个路由允许2个以上的并发连接。