我的啓用RMI的應用程序似乎在泄露套接字。我有一個Java應用程序通過RMI提供服務。它使用在Linux上運行的Java SE 1.6 RMI實現。我觀察到的問題是,如果客戶端使用註冊表獲取對Remote對象的引用,然後突然斷開連接(斷電,拔掉電纜等),服務器將保持套接字打開。我希望在客戶的租約到期後清理RMI實現,但這不會發生。在服務器上,當租約到期時調用Remote對象的unreferenced()
方法,但套接字在netstat中始終以「ESTABLISHED」狀態無限期地可見。租約到期後Java RMI未關閉套接字
由於我們無法強制客戶端進入任何特定行爲,因此在幾天後,我們在Linux發行版中達到默認限制1024(對於打開文件描述符),導致服務器無法打開任何新套接字或文件。我想過TCP keepalive,但是由於RMI正在抽象掉網絡層,所以在建立連接後,我無法訪問實際的服務器套接字。
有沒有什麼辦法強制RMI層清理與過期租約的客戶端連接綁定的套接字?
更新:我使用的解決方案與所選答案類似,但使用了不同的方法。我使用了一個自定義的套接字工廠,然後將包含createServerSocket()返回的ServerSocket實例包裝在一個透明的包裝器中,該包裝器通過了所有方法,accept()除外。在accpet方法中,keepalives在返回套接字之前啓用。
public class KeepaliveSocketWrapper extends ServerSocket
{
private ServerSocket _delegate = null;
public KeepaliveSocketWrapper(ServerSocket delegate)
{
this._delegate = delegate;
}
public Socket accept() throws IOException
{
Socket s = _delegate.accept();
s.setKeepAlive(true);
return s;
}
.
.
.
}
好的解決辦法;你應該輸入它作爲答案,以便我可以投票! – erickson 2008-10-29 18:07:34
爲什麼你更喜歡它到MySocketFactory?你的項目有什麼優勢? – 2008-11-06 12:06:41