我使用從的Java HTTPGET,在服務錯誤打開的文件太多
進口org.apache.http.client.methods.HttpGet REST式HTTPGET服務;
我創建了一個函數來查詢另一臺計算機上的服務。該電話工作正常,但我遇到了「太多打開文件」的服務。我的方面只是返回一個500錯誤,我發現。
我跟供應商談過了,他們非常堅定地認爲RESTful呼叫應該以持續的方式進行,並且我根本沒有釋放某些東西,並繼續說問題出在我身上。
我寫了一個壓力函數,見下文,以幫助隔離問題。據我所知,我釋放了一切。我對Java仍然很陌生,所以我只是沒有看到一些不清楚的東西。
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
public void doStressTest()
{
String strUri = "http://<ip address>:<port>/task?vara=dataa&varb=datab";
HttpGet oRestyGet = new HttpGet();
oRestyGet.addHeader("Accept", "application/xml");
for (int iLoop = 0; iLoop < 1000; iLoop++)
{
CloseableHttpClient httpclient = HttpClients.createDefault();
try
{
oRestyGet.setURI(new URI(strUri));
try
{
CloseableHttpResponse response2 = httpclient.execute(oRestyGet);
try
{
String strResponseHeader = response2.getStatusLine().toString();
if (false == "HTTP/1.1 200 OK".equalsIgnoreCase(strResponseHeader))
return;
continue;
}
finally
{
response2.close();
}
}
catch (ClientProtocolException e)
{
e.printStackTrace();
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
try
{
httpclient.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
try
{
oRestyGet.releaseConnection();
}
catch (Exception e)
{
e.printStackTrace();
}
}
更新: 我以爲我想補充的廠商不得不說的文本,以防萬一這可能幫助。我應該補充一點,在下面的壓力測試中,我打開了一個HTTP GET請求對象,這對我的「會話」是持久的,並用於整個請求。
這意味着系統正在運行FDs,爲用戶運行 的過程。當開放式套接字或FD太多時會發生這種情況。 通常對於HTTP,強烈建議HTTP請求是以持久方式發送的 ,也就是說,您有一個用於整個會話的HTTP連接,並且不會爲每個請求打開多個HTTP連接,然後關閉 這些連接。更多的時候,你不會結束揮之不去的 連接。
我正在關閉「可關閉」的CloseableHttpClient,我也不認爲我需要只有一個。我應該補充一點,「我」並沒有耗盡任何東西,服務是。該供應商似乎認爲該服務與OS一樣是完美的。還能做些什麼來隔離問題?
更新2: (我把日誌文件從服務供應商,他們有下面要說的膠着狀態。?)
它看起來像問題是,有太多的連接通過您的界面打開 。我通過Firefox的 包含了一個會話的日誌文件。您可以看到如何使用瀏覽器通過同一連接發出多個HTTP請求。
只有一個線,其中初始連接時從[127.0.0.1] ...允許
隨後的GET請求是來自同一連接
HTTP連接。
...您的日誌文件顯示:HTTP從[192.168.20.123] ...允許
連接每個GET請求你讓着,這些連接都沒有關閉。
UPDATE 3: 我有權訪問服務生成的日誌,但無法訪問源。 Java的問題的連接,並響應於行GET請求作爲一個包:
我發出httpclient.close(),它不產生日誌條目,所以我懷疑是服務根本沒有響應對此。
由於我不熟悉另一端的機制,可能服務只是響應事件,問題在於CENTOS未正確處理close()調用。無論哪種方式,使用這種方法,問題不是我的。證明這是另一回事。另一種選擇是某種其他解決方案,可以正確地釋放資源。
您是否嘗試過使用持久性/流水線HTTP 1.1連接? –
我不確定那是什麼或代碼將如何改變。 –