2011-03-24 35 views
0

好的,我得到如何使用RMI綁定具有衆所周知名稱的單例服務器對象,以便其他JVM可以找到它。java RMI和/或JNDI:綁定非單身對象

假設我有多個進程,每個進程運行一個JVM,並且每個進程都創建一個支持FooRemote接口的對象,我希望通過RMI公開接口。每個進程都有一個不可預知的生命週期,與用戶輸入或資源可用性相對應。

如何綁定這些而不會發生命名衝突?會使用JNDI有幫助嗎?

實際上,我希望做的是擁有一個類似對象池,每個對象都在單獨的JVM上(原因很重要,但超出了此問題的範圍)。我需要一個客戶端來枚舉哪些對象可用,並選擇一個用於進一步的交互。我強調單獨的JVM的原因是,如果它們都在同一個JVM中,我可以只有一個單獨管理器來處理組池,並通過管理器使所有組實例都可以訪問,但我可以如果組池由獨立的JVM中的獨立實例組成,則不會這樣做。)

回答

2

這不是非常有效,但是您可以在每個JVM中創建並枚舉池中的所有對象屬於該JVM。

您顯然必須要求他們全部獲取完整圖片。根據您的實際使用情況,這可能是也可能不是您想要的。雖然這是準確的,但網絡流量和延遲會嚴重影響性能,所以如果您查詢池的次數超過了更新次數,請不要嘗試此操作。

另一種解決方案是將客戶端變爲服務器,並允許服務器在池中對象的狀態發生更改時調用回調。此解決方案可能在網絡流量中效率更高,但不及時更新:如果其中一臺服務器突然終止,則在您真正嘗試使用它們並失敗之前,其對象不會從池中移除。這種行爲可以通過Keepalive調用和超時來改善,以跟蹤服務器的可用性,但顯然會以增加流量和解決方案的複雜性爲代價。

+0

...但這不是雞雞蛋問題嗎?比方說,我有5個JVM運行相同的代碼,每個JVM都有一個工廠。我爲每個工廠選擇了哪些RMI綁定名稱,以及如何枚舉工廠?如果我能回答這些問題,我可以解決我原來的問題(因爲在我的情況下,每個JVM只有一個RMI導出的對象)。 – 2011-03-24 18:07:16

+0

您可以創建一個子上下文,選擇一個隨機名稱(例如'UUID.randomUUID()'),並將該對象放在該上下文中的隨機名稱下。要找到它們,你可以執行'InitialContext.listBindings()',它將返回上下文中的所有對象。 – biziclop 2011-03-24 22:02:11

+0

啊:那就解決問題吧!那是JNDI,對吧?你可以編輯你的答案+給我一個例子,或者指向一個使用JNDI + RMI w/subcontexts的在線人員嗎?這對我來說有點奇怪。 – 2011-03-24 22:34:10