首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >HttpClient无法从服务器获得响应

HttpClient无法从服务器获得响应
EN

Stack Overflow用户
提问于 2014-01-02 09:58:29
回答 2查看 4.2K关注 0票数 3

这个问题妨碍了我们全队半天!

我们使用ApachehttpClient4.3.x从提供http的存储服务器上发布和获取数据。为了提高性能,我们使用了PoolingHttpClientConnectionManager

代码语言:javascript
运行
复制
public HttpClient createHttpClient() {
    Registry registry = RegistryBuilder.create()....build();
    PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
    connectionManager.setMaxTotal(50);
    connectionManager.setDefaultMaxPerRoute(50);

    CloseableHttpClient httpClient = HttpClients.custom()
       .setConnectionManager(connectionManager)
       .build();
    return httpClient;
}

然后,我们在我们的程序中保存一个httpClient实例,在每个http请求中重用它:

全球httpClient:

代码语言:javascript
运行
复制
HttpClient httpClient = createHttpClient();

发布一些数据:

代码语言:javascript
运行
复制
HttpPost httpPut = new HttpPost("...");
HttpResponse response = httpClient.execute(httpPut);

// Notice we get the response content here!
String content = EntityUtils.toString(response.getEntity());
System.out.println(content);

httpPut.releaseConnection();
response.close();

那就得到:

代码语言:javascript
运行
复制
HttpGet httpGet = new HttpGet("...");

// Blocked at this line !!!!
HttpResponse response = httpClient.execute(httpGet);

String content = EntityUtils.toString(response.getEntity());
System.out.println(content);

httpPut.releaseConnection();
response.close();    

请注意这一行:// Blocked at this line !!!!

程序在那一行已经阻塞,永远不会转到下一行。在调试模式中,我可以看到它在以下位置被阻塞:

代码语言:javascript
运行
复制
SocketInputStream.socketRead0()

我找了很多问题和文件,但运气不好。

我的同事只要设置NoConnectionReuseStrategy.INSTANCE就可以解决这个问题

代码语言:javascript
运行
复制
 HttpClients.custom()
       .setConnectionManager(connectionManager)
       // Following line fixed the problem, but why?
       .setConnectionReuseStrategy(NoConnectionReuseStrategy.INSTANCE)
       .build();

现在它没有被阻止,但为什么?

“重用连接”是什么意思?使用NoConnectionReuseStrategy是否存在性能问题?

谢谢,伙计们~

EN

回答 2

Stack Overflow用户

发布于 2014-01-08 00:10:17

我试着复制阻塞的http-get (也是我自己的练习),但是即使没有结束语,我也无法阻止它。我唯一成功地创建http块的方法是执行一个response.getEntity().getContent(),而不读取返回的InputStream,也不关闭返回的InputStream。在我的测试中,我使用Tomcat 7.0.47作为服务器,并将两个非常简单的servlet(一个响应为get,另一个响应post)作为服务器。客户机启动50个线程,每个线程执行30个交替的http和http请求(总共1500个请求)。客户端没有使用RegistryBuilder,而是使用默认的(由PoolingHttpClientConnectionManager本身创建)。

关于NoConnectionReuseStrategy:默认情况下(使用HttpClients.createDefault()创建的HttpClient,我使用了org.apache.httpcomponents:httpclient:4.3.1),连接池最多使用两个连接到一个服务器。例如,即使5个线程同时对一个服务器执行各种请求,连接池也只打开两个连接,对所有请求重新使用它们,并确保在任何给定的时间由一个线程使用一个连接。这可以对客户端性能产生非常积极的影响,并显著减少服务器上的负载。唯一需要确保的是在一个最终块中调用response.close() (这可以确保连接返回到连接池)。通过使用NoConnectionReuseStrategy,您基本上禁用了连接池:对于每个请求,将创建一个新连接。我建议您为类别org.apache.http.impl.conn.PoolingHttpClientConnectionManager启用调试日志记录,它非常有用.

关于httpPut.releaseConnection()的一个注意事项:这实际上并不会释放一个连接,它只会确保您可以在下一个请求中重用"httpPut“对象(参见尖点,按照显示的链接)。还请注意,在"httpGet“的代码中,您在"httpPut”而不是"httpGet“上调用了releaseConnection()

票数 4
EN

Stack Overflow用户

发布于 2014-09-11 04:32:28

不久前就遇到了这个问题。如果其他人遇到了这个问题,这篇文章可能会很有用。

我正在使用Java来服务我的请求。当我使用PrintWriter实例写入响应流时,我的客户端阻塞了它。尝试直接写到OutputStream,response.getOutputStream.write("myresponse")就成功了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20880325

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档