RMI createRegistry延迟问题
我在从 JVM 中创建 RMI 注册表时遇到了一个奇怪且间歇性的问题。这些代码将全部在内部网上运行,其想法是能够轻松地在一堆机器上启动服务。
public static <X, Y> void newServer(Function<X, Y> function, String name)
throws Exception {
FunctionServer<X, Y> fun = null;
RemoteFunction<X, Y> stub = null;
Registry registry = null;
try {
fun = new FunctionServer<X, Y>(function);
stub = (RemoteFunction<X, Y>) UnicastRemoteObject.exportObject(fun, 0);
}
catch (RemoteException e1) {
e1.printStackTrace();
}
boolean foundPort = false;
int port = 1099;
do {
try {
registry = LocateRegistry.createRegistry(port);
registry.rebind(name, stub);
// Thread.sleep(100);
foundPort = true;
}
catch (ExportException e) {
port++;
}
catch (Exception e) {
e.printStackTrace();
throw e;
}
} while (!foundPort);
if (registry.lookup(name) != null)
System.out.println("Service " + name + " serving "
+ function.getClass().getCanonicalName() + " on port " + port);
}
当然有一个非常简单的 main 方法:
FileSystemXmlApplicationContext context =
new FileSystemXmlApplicationContext(args[0]);
Object obj = context.getBean(args[1]);
if (obj instanceof Function<?, ?>) {
Function<?, ?> fun = (Function<?, ?>) obj;
FunctionServer.newServer(fun, args[2]);
}
从命令行调用代码如下:
java -cp daopt.jar -Djava.rmi.server.codebase="file://daopt.jar" ****.*******.remote.FunctionServer spring/rosenbrockServer.xml rosenbrock rosenbrock
但有时,它会默默地失败。它打印成功服务器启动消息,但随后没有 java 进程运行,并且 netstat -anp | grep [portNumber] 没有显示任何内容。值得注意的是,如果我在 newServer 方法中添加延迟,即取消注释该行,
Thread.sleep(100);
则一切正常。这是否意味着 LocateRegistry.createRegistry 正在启动某种工作线程,该线程在一段时间后抛出异常?这是怎么回事?
困惑,
开发者
I'm experiencing a strange and intermittent problem creating an RMI registry from within the JVM. This code will all be run on an intranet, and the idea is to be able to launch services on a bunch of machines easily.
public static <X, Y> void newServer(Function<X, Y> function, String name)
throws Exception {
FunctionServer<X, Y> fun = null;
RemoteFunction<X, Y> stub = null;
Registry registry = null;
try {
fun = new FunctionServer<X, Y>(function);
stub = (RemoteFunction<X, Y>) UnicastRemoteObject.exportObject(fun, 0);
}
catch (RemoteException e1) {
e1.printStackTrace();
}
boolean foundPort = false;
int port = 1099;
do {
try {
registry = LocateRegistry.createRegistry(port);
registry.rebind(name, stub);
// Thread.sleep(100);
foundPort = true;
}
catch (ExportException e) {
port++;
}
catch (Exception e) {
e.printStackTrace();
throw e;
}
} while (!foundPort);
if (registry.lookup(name) != null)
System.out.println("Service " + name + " serving "
+ function.getClass().getCanonicalName() + " on port " + port);
}
There is of course a very simple main method:
FileSystemXmlApplicationContext context =
new FileSystemXmlApplicationContext(args[0]);
Object obj = context.getBean(args[1]);
if (obj instanceof Function<?, ?>) {
Function<?, ?> fun = (Function<?, ?>) obj;
FunctionServer.newServer(fun, args[2]);
}
The code is invoked from the command line as follows:
java -cp daopt.jar -Djava.rmi.server.codebase="file://daopt.jar" ****.*******.remote.FunctionServer spring/rosenbrockServer.xml rosenbrock rosenbrock
Sometimes, though, it fails silently. It prints the successful server start message, but then there is no java process running, and netstat -anp | grep [portNumber] shows nothing. Remarkably, if I put in a delay in the newServer method i.e., uncomment the line
Thread.sleep(100);
it all works fine. Does this mean that LocateRegistry.createRegistry is launching some sort of worker thread that throws an exception after a while? What's going on?
Flummoxed,
Dev
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使“registry”变量成为静态成员。目前它正在被垃圾收集,从而取消导出它,并允许服务器进行 DGC,从而允许进程退出。
您不需要那个 do/while 循环。使用Registry.REGISTRY_PORT。这就是它的用途。由 IANA 为 RMI 注册管理机构保留。
Make the 'registry' variable a static member. At the moment it is being garbage-collected, which unexports it, and allows the server to be DGC'd, which allows the process to exit.
You don't need that do/while loop. Use Registry.REGISTRY_PORT. That's what it's for. Reserved at IANA for the RMI Registry.
在 JVM 中使用 LocateRegistry.createRegistry 时,建议使用
When using LocateRegistry.createRegistry within the JVM, it's advisable to use