如何获取java.rmi.Remote实例的状态

时间:2016-08-21 14:18:01

标签: java rmi

我有一个实现A的类java.rmi.Remote的实例。

为了检查与RMI服务器的连接的健康状况,我调用了A实例的一个定制的,简单的成员函数,并查看是否抛出了异常。那不是很优雅。因此我的问题是:

是否有任何 native 方法来检查连接是否可用于A实例上的方法调用,即无需实际尝试调用成员函数?

特殊情况是:如果在客户端A实例的生命周期内重新启动RMI服务器,则A的实例将变为无效,失效(虽然服务器可能会恢复正常)。

2 个答案:

答案 0 :(得分:2)

来自Java RMI FAQ

  

F.1在什么时候有一个" live"客户与客户之间的联系   服务器以及如何管理连接?

     

当客户进行"查找"操作,连接到   rmir​​egistry在指定的主机上。通常,新连接可以或   可能无法为远程呼叫创建。连接由缓存   Java RMI传输以供将来使用,因此如果连接是免费的   远程呼叫的正确目的地,然后使用它。客户不能   显式关闭与服务器的连接,因为连接是   在Java RMI传输级别进行管理。连接将超时   它们在一段时间内未被使用。

您的问题:

  
      
  1. 是否有任何本机方式来检查连接是否可用   对A实例的方法调用,即不需要   实际上尝试调用成员函数?
  2.   

这个问题归结为如何以编程方式检查给定的服务器/系统是否已启动。这个问题已经在这里和其他几个论坛得到了多次回答。回答这个问题的一个问题是Checking if server is online from Java code

  
      
  1. 特殊情况是:在此期间是否应重新启动RMI服务器   客户端A的实例的生存期,然后是实例   A变为无效并且不存在(尽管服务器可能已备份   和健康)。
  2.   

然后,答案很简单。如果类的实例忙于在远程方法调用中执行步骤,则会立即抛出与连接相关的异常。

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

  

如果客户端和服务器之间保持打开TCP连接   在整个交互过程中,服务器都可以检测到客户端   稍后尝试写入连接时重启(我在这里添加,反之亦然)   失败(包括每小时TCP keepalive数据包,如果启用)。   但是,Java RMI的设计并不需要这样的永久性   客户端和服务器(或同级)之间的连接,因为它的损害   可扩展性并没有多大帮助。

     

鉴于绝对不可能立即确定何时   网络对等体崩溃或变得不可用,你必须决定   当对等方停止响应时,应用程序应该如何表现。

查找将继续完美运行,直到服务器启动并且在客户端对远程方法执行操作时不会停止运行。如果对等体重新启动,您必须在此决定应用程序的行为方式。此外,RMI中没有会话这样的概念。

我希望这能解答你所有的问题。

答案 1 :(得分:1)

你的问题是建立在谬论之上的。

提前了解状态对您没有任何帮助。状态测试之后是一个计时窗口,然后是您使用服务器。在定时窗口期间,状态可以改变。当您使用时,测试时可以启动服务器。或者在您使用时测试时可能会关闭。

确定任何资源是否可用的正确方法是尝试使用它。这适用于输入文件,RMI服务器,Web系统......

  

如果在客户端A的实例生命周期内重新启动RMI服务器,则A的实例将变为无效并且不存在(尽管服务器可能已备份且运行正常)。

在这种情况下,您将获得java.rmi.ConnectExceptionjava.rmi.NoSuchObjectException,具体取决于远程对象是在不同的端口还是在同一端口上重新启动。