2016-08-21 46 views
2

我有一個實例A實現java.rmi.Remote如何獲取java.rmi.Remote實例的狀態

爲了檢查到RMI服務器的連接的健康狀況,我調用了A實例的定製的簡單成員函數,並查看是否拋出異常。這不是很高雅。所以我的問題:

是否有檢查連接可用的方法調用上的A,即實例,而不需要實際嘗試調用一個成員函數的任何本地方式?

一種特殊情況是:如果RMI服務器的A在客戶端實例的生命週期內重新啓動,那麼A實例變爲無效,解散(雖然服務器可能是備份和健康) 。

+0

這不取決於你的代碼嗎?如果您的實例正在執行某些操作,但尚未返回,則立即無法執行其他方法調用。就像從前一次調用返回一樣,它將處理其他方法調用。 –

+0

感謝您的評論!對於我的問題,讓我們假設實例是_忙於做某事,即未陷入方法中。我的問題只涉及實例的連接狀態。 – datahaki

+0

如果應用程序當前正在實例的範圍內運行,那麼YES,該對象將不會被GC回收。所以,我相信,您可以放心地假定該對象可供您執行其任何方法調用。 –

回答

2

Java RMI FAQ

F.1在什麼時候有客戶端和 服務器以及如何之間的「活」連接的連接管理?

當客戶端執行「查找」操作時,將連接到指定主機上的rmiregistry。通常,可能不會爲遠程呼叫創建新的連接或可能會創建新的連接。連接由 Java RMI傳輸緩存以供將來使用,因此如果連接對於遠程調用的正確目的地是免費的,那麼它將被使用。客戶端不能 顯式關閉與服務器的連接,因爲在Java RMI傳輸級別上管理的連接是 。如果 這些連接在一段時間內未被使用,連接將會超時。


您的問題:

  1. 是否有檢查,如果連接可用於在A,即實例 方法調用,而不需要 任何本地方式其實嘗試調用成員函數?

這個問題歸結爲如何以編程方式檢查給定的服務器/系統是否已啓動。這個問題已經在這裏和其他幾個論壇上被回答了幾次。回答這個問題的一個這樣的問題是Checking if server is online from Java code

  • 一種特殊情況是:應RMI服務器的 壽命A的在客戶端實例的過程中被重新啓動,然後 A的實例變爲無效和被禁(儘管服務器可能會備份並且健康)。
  • 然後,答案很簡單。如果類的實例正忙於在遠程方法調用中執行一個步驟,則會立即拋出與連接有關的異常。

    再次,from RMI FAQ, D.8 Why can't I get an immediate notification when a client crashes?

    如果TCP連接時舉行的客戶和整個交互服務器 之間的開放,那麼服務器可以檢測客戶端 重啓(我加入這裏:和反之亦然)當稍後嘗試寫入連接 失敗時(包括每小時TCP保持活動數據包,如果啓用)。然而,Java RMI被設計爲不需要在客戶端和服務器(或對等端)之間永久連接永久的連接,因爲它損害了可伸縮性,並且沒有多大幫助。

    由於絕對不可能立即確定何時 網絡節點崩潰或變得不可用,因此您必須決定 當對等節點停止響應時應用程序的行爲。


    查找將保持在完美的工作,直到服務器啓動並在客戶端上的遠程方法執行操作不下來。您必須在此決定您的應用程序在對等設備重新啓動時應該如何處理。另外,在RMI中沒有會話這樣的概念。

    我希望這能回答你所有的問題。

    1

    你的問題是建立在謬誤上。

    事先了解身份並沒有絲毫幫助你。狀態測試之後是一個時間窗口,隨後是您使用服務器。在時間窗口期間,狀態可能會改變。使用時,服務器在測試時可能會啓動。或者當你測試時它可能會關閉,當你使用它時可能會關閉。

    確定是否有任何資源可用的正確方法是嘗試使用它。這適用於輸入文件,RMI服務器,Web系統,...

    如果RMI服務器A對客戶端的實例的生命週期內重新啓動,那麼A的實例變得無效,解散(儘管服務器可能已經恢復並且健康)。

    在這種情況下,你會得到無論是java.rmi.ConnectException或根據遠程對象是否不同的端口或同一端口上重新啓動,java.rmi.NoSuchObjectException

    相關問題