2009-09-08 61 views
1

我有一個基於Java和Tomcat的服務器應用程序,它向其他網站發起許多出站HTTP請求。我們使用雅加達的HTTP核心/客戶端庫,非常新的版本。多個完整的HTTP請求停留在TCP CLOSE_WAIT狀態

服務器在某些時候鎖定,因爲它的所有工作線程都試圖關閉完成的HTTP連接。使用'lsof'會顯示一堆卡在TCP CLOSE_WAIT狀態的套接字。

這不會發生在所有甚至大多數連接上。事實上,我之前看到它,並通過確保設置連接:關閉響應標題來解決它。所以這讓我認爲這可能是遠程服務器的不良行爲。

自從我將應用程序遷移到全新的服務提供商 - 不同的操作系統,網絡情況以來,它可能再次出現。

但是,如果有什麼,我仍然無法解決這個問題。有些在互聯網上徘徊沒有發現任何我沒有做過的事情。只是想我會問是否有人看到並解決了這個問題?

+0

我也看到了。也許移動到serverfault會產生更多的答案 – 2009-09-08 14:17:44

回答

1

我相信我可能已經找到了一個解決方案 - 至少,這些改變一起,似乎讓問題消失了。

  • 呼叫HttpEntity.consumeContent()你完成從它的InputStream看完後,要仔細檢查內容被消耗,框架釋放連接
  • 良好的措施,我稱之爲ClientConnectionManager.closeExpiredConnections()和ClientConnectionManager.closeIdleConnections(0L,TimeUnit.MILLISECONDS)之後,按下框架即可釋放它立即完成的任何事情。這可能是矯枉過正。

OK上面也不太做的伎倆。最後,我必須使用SingleClientConnManager,併爲每個請求創建並關閉它。這個伎倆。我認爲這是確保連接關閉所需的。

2

我不確定你對TCP有多瞭解。當TCP客戶端處於ESTABLISHED狀態並收到FIN數據包時,它將以CLOSE_WAIT狀態結束。 CLOSE_WAIT狀態意味着它正在等待從應用程序層收到close命令 - 在這種情況下,這意味着它正在等待在套接字上調用close()

所以,我的猜測是,在工作線程中調用close()將解決問題。或者你已經在做這個?

+0

是的,我得到了很多,但我認爲我們正確使用雅加達庫,它幾乎可以在所有連接上正常工作。但我同意,這似乎是要深入研究的部分。我會看看這些連接是否真的被圖書館關閉。 – 2009-09-08 18:04:35

+0

你看到在'CLOSE_WAIT'中掛起的連接和那些沒有連接的連接有什麼不同?它始終如一嗎? – 2009-09-08 18:36:07

+0

是的,這是對同一對夫婦。我相信它必須與遠程主機如何處理連接有關,但是我不知道該如何解決該問題。我確實看到連接始終在應用程序層的Java端關閉。 – 2009-09-09 11:27:56