我有几个导出RMI接口的服务。
他们过去通过创建自己的注册表(使用LocateRegistry.createRegistry
)并将其绑定到那里来提供这一功能。然而,当服务被移动到同一VM(Tomcat)中作为单独的应用程序运行时,这就变得不可能了,因为出于某种原因,那里只能存在一个注册表。
我通过使用所有服务的中央注册表来解决这个问题。即便如此,我对注册表的多对象注册表角色并不是很感兴趣,只是它的入口点功能。然而,中央注册中心引入了更多的复杂性(例如,它必须首先启动,它必须具有它注册的服务的接口)。
有没有一种方法可以让每个服务独立地为其RMI接口提供一个入口点,同时让它们在同一个VM中运行(这是托管细节,而不是设计的一部分)?
我忘了我已经问了一个类似的问题(出于不同的原因,在我在1个VM中移动服务之前,减少了代码),其中第一个答案建议了一种绕过注册表的方法:
使用UnicastRemoteObject,序列化导出时获得的存根对象,并使用共享文件、套接字或sneernet客户端可用的存根。
每个JVM不能有一个以上的注册表,因为注册表有一个固定的RMI对象ID。只需调整所有服务器即可启动,如下所示:
static Registry registry;
// ...
try
{
registry = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
}
catch (...) // whatever the exception is, probably ExportException
{
registry = LocateRegistry.locateRegistry(Registry.REGISTRY_PORT);
}
registry.rebind(...); // etc
然后,无论哪一个先启动,都将启动注册表,其他人将使用它。
如果一年后你仍然对这个问题感兴趣。。。。
可以在同一JVM中启动多个注册表。只需使用不同的端口调用LocateRegistry.getRegistry
即可。每个服务都必须有众所周知的端口,但我认为,如果您已经实现了从这个答案到另一个问题的选项3,那么您就已经做到了。
很久以前,有一个错误阻止多个注册表在同一JVM中共存,但JDK5中已经修复了这个错误。Tomcat中可能存在阻止多个RMI注册表运行的内容。或者,可能是您使用的Tomcat版本位于一个非常旧的JDK之上。