Java 是否有一种有效的方法来测试RMI服务器是否已启动?
我有一个RMI客户端测试RMI服务器是否正在运行并且可以访问 此时,我每隔几秒钟执行一次此测试:Java 是否有一种有效的方法来测试RMI服务器是否已启动?,java,rmi,Java,Rmi,我有一个RMI客户端测试RMI服务器是否正在运行并且可以访问 此时,我每隔几秒钟执行一次此测试: try { rMIinstance.ping(); } catch (RemoteException e) { getInstanceRegister().removeInstance(rMIinstance); } (ping()是一个简单的虚拟RMI调用。) 如果实例处于脱机状态,我将在大约1分钟后获得 java.net.ConnectException:连接超时 异常,显示服
try {
rMIinstance.ping();
} catch (RemoteException e) {
getInstanceRegister().removeInstance(rMIinstance);
}
(ping()
是一个简单的虚拟RMI调用。)
如果实例处于脱机状态,我将在大约1分钟后获得
java.net.ConnectException:连接超时
异常,显示服务器处于脱机状态
然而,代码挂起一分钟,这对我们来说太长了。(我不想更改超时设置。)
是否有方法更快地执行此测试?您可以从计时器中断线程。它有点黑客化,将抛出InterruptedException而不是RemoteException,但它应该可以工作
try {
Timer timer = new Timer(true);
TimerTask interruptTimerTask = new InterruptTimerTask(Thread.currentThread());
timer.schedule(interruptTimerTask, howLongDoYouWantToWait);
rMIinstance.ping();
timer.cancel();
} catch (RemoteException | InterruptedException e) {
getInstanceRegister().removeInstance(rMIinstance);
}
以及TimerTask实现:
private static class InterruptTimerTask extends TimerTask {
private Thread thread;
public InterruptTimerTask(Thread thread) {
this.thread=thread;
}
@Override
public void run() {
thread.interrupt();
}
}
受@NeplatnyUdaj答案的启发,我找到了以下解决方案:
try {
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<String> future = executor.submit(new Task(rMIinstance));
System.out.println("Result: "+ future.get(3, TimeUnit.SECONDS));
} catch (RemoteException | TimeoutException e) {
getInstanceRegister().removeInstance(rMIinstance);
}
试试看{
ExecutorService executor=Executors.newSingleThreadExecutor();
Future=executor.submit(新任务(rminstance));
System.out.println(“结果:+future.get(3,TimeUnit.SECONDS));
}捕获(RemoteException | TimeoutException e){
getInstanceRegister().removeInstance(RMInstance);
}
这项任务是:
class Task implements Callable<String> {
DatabaseAbstract rMIinstance;
public Task(DatabaseAbstract rMIinstance)
{
this.rMIinstance = rMIinstance;
}
@Override
public String call() throws Exception {
rMIinstance.ping();
return "OK";
}
}
类任务实现可调用{
数据库抽象实例;
公共任务(数据库抽象实例)
{
this.rminstance=rminstance;
}
@凌驾
公共字符串调用()引发异常{
rMIinstance.ping();
返回“OK”;
}
}
中断发出RMI调用的线程的建议解决方案可能不起作用,这取决于该线程是否处于可以中断的位置。普通正在进行的RMI呼叫不可中断
尝试将系统属性java.rmi.server.disableHttp
设置为true
。由于RMI正在故障转移到其HTTP代理机制,因此可能发生长连接超时。此机制在的类文档中进行了描述(尽管非常简短)。(HTTP代理机制在JDK 8中已被弃用)。将系统属性设置为所需的连接超时(以毫秒为单位)。我也会设置
建议中断线程的答案取决于
java.net
的特定于平台的行为,其行为在被中断时是未定义的。只是一个小提示:通常您会重用ExecutorService
,因为它的目的是“缓存”线程。感谢关于中断的提示。超时的问题是,这个VM上的其他RMI实例应该对超时有一定的容忍度。因此,使用适合于其他远程方法的更长超时,并完全去掉这个。如果超时过期,其他方法将抛出异常。我测试了java.rmi.server.disableHttp
=true
。这并没有减少长时间的连接超时。哦,好吧,值得一试。当这种情况发生时,听起来您有一个低级连接问题。在尝试RMI之前,请先尝试ping以查看主机是否可访问并作出响应。