![](/img/trans.png)
[英]Can I get the response server name/ip using Apache HttpClient?
[英]HttpClient can't get response from server
這個問題已經使我們的整個團隊半天無法工作了!
我們使用apache httpclient 4.3.x來發布並從提供http api的存儲服務器中獲取數據。 為了提高性能,我們使用了PoolingHttpClientConnectionManager
:
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:
HttpClient httpClient = createHttpClient();
發布一些數據:
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();
然后得到:
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 !!!!
程序已在該行被阻止,並且從不進入下一行。 在調試模式下,我可以看到它已在以下位置被阻止:
SocketInputStream.socketRead0()
我搜索了很多問題和文檔,但並不幸運。
我的NoConnectionReuseStrategy.INSTANCE
只是通過設置NoConnectionReuseStrategy.INSTANCE
解決它:
HttpClients.custom()
.setConnectionManager(connectionManager)
// Following line fixed the problem, but why?
.setConnectionReuseStrategy(NoConnectionReuseStrategy.INSTANCE)
.build();
現在它沒有被阻止,但是為什么呢?
“重用連接”是什么意思? 使用NoConnectionReuseStrategy
是否存在性能問題?
謝謝大家〜
我試圖重現阻止的http-get(也是我自己的一種練習),但是即使沒有關閉響應,我也無法阻止它。 我設法制作http-get塊的唯一時間是通過執行response.getEntity().getContent()
而不讀取返回的InputStream
且不關閉返回的InputStream
。 在我的測試中,我將Tomcat 7.0.47與兩個非常簡單的servlet(作為響應get響應“ OK”,另一個響應POST)用作服務器。 客戶端啟動了50個線程,每個線程執行30個交替的http-get和http-post請求(總共1500個請求)。 客戶端未使用RegistryBuilder
,而是使用默認值(由PoolingHttpClientConnectionManager
本身創建)。
關於NoConnectionReuseStrategy
:默認情況下(使用HttpClients.createDefault()
創建的HttpClients.createDefault()
,我使用的是org.apache.httpcomponents:httpclient:4.3.1
),連接池最多使用1個服務器的2個連接。 例如,即使5個線程同時對1個服務器執行各種請求,連接池也僅打開2個連接,將它們重新用於所有請求,並確保在任何給定時間1個線程使用1個連接。 這會對客戶端性能產生非常積極的影響,並顯着減少服務器上的負載。 您唯一必須確保的是在finally塊中調用response.close()
(這可確保將連接返回到連接池)。 通過使用NoConnectionReuseStrategy
您基本上可以禁用連接池:對於每個請求,將創建一個新的連接。 我建議您為org.apache.http.impl.conn.PoolingHttpClientConnectionManager
類別啟用調試日志記錄,這非常有用。
關於httpPut.releaseConnection()
注釋:實際上並不會釋放連接,它只是確保您可以在下一個請求中重用“ httpPut”對象(請參閱apidocs , 單擊顯示的鏈接)。 另請注意,在“ httpGet”的代碼中,您在“ httpPut”而不是“ httpGet”上調用releaseConnection()
。
不久前就遇到了這個問題。 如果其他人遇到此問題,這篇文章可能會有用。
我正在使用Java Servlet來處理我的請求。 當我使用PrintWriter實例寫入響應流時,客戶端被阻止。 嘗試直接寫入到OutputStream的response.getOutputStream.write("myresponse")
並成功。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.