我的RMI应用程序出现问题。大约20小时后(+/-几个小时),客户端无法再连接。在服务器一生的前20个小时内,尽管我可以根据需要创建尽可能多的连接。我怀疑与RMI远程对象是garbacge收集有指向它的引用的一个问题,但我可以排除这种可能性有2个原因:为什么我的RMI服务器在20小时后死亡
- 我不得不运行在JVM服务器做使用jconsole一个GC并且客户端仍然可以连接
- 我在主方法中持有对我的服务器的引用,我不退出,RMI注册表和存根都是我的服务器类的成员。
我的服务器在端口1099上创建一个RMI注册表,并在端口5099上作为UnicastRemoteObject导出。当客户端在20小时后无法再连接时,我得到一个java.rmi.ConnectException。要清除服务器的java进程仍在运行,注册表(在该进程中运行)仍然响应并返回远程对象。我在客户端调用远程方法时抛出异常。
如果我在我的服务器机器上执行“netstat -tulpn”,我可以看到java进程最初正在侦听端口5099,但是一旦20小时错误在服务器上启动,就不再监听该端口。我想我也可以排除防火墙问题,因为我禁用了服务器防火墙进行测试。以下是我的代码的简化版本。任何关于那里发生的事情以及如何使服务器无懈可击的意见都将不胜感激。干杯!
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class MyRMIServer implements MyRMIInterface {
private MyRMIInterface stub;
private Registry registry;
public static void main(String[] args)
{
MyRMIServer server = new MyRMIServer();
server.startRmiServices();
// now sleep, don't let the main thread die, otherwise we might loose our ref to the
// RMI stub and/or registry
while (true)
{
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void startRmiServices()
{
try {
// set up security manager
if (System.getSecurityManager() == null) {
System.setSecurityManager(new SecurityManager());
}
// create stub
stub = (MyRMIInterface) UnicastRemoteObject.exportObject(this,5099);
// Bind the remote object's stub in the registry
registry = LocateRegistry.createRegistry(1099);
registry.rebind("MyServer", stub);
System.out.println("RMI ready");
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public synchronized int remoteCall(int x) throws RemoteException
{
return x+1;
}
}
定义“无法再连接”。抛出什么异常? – EJP
服务器上的任何错误?告诉我们你的日志。 –
@stonedsquirrel在这个阶段,客户端的错误更加有趣。 – EJP