我试图在Single(96 Ram)Machine上运行3个RMI服务器。从三个不同的机器客户端调用,但对于三个客户端,我已经给出了3个不同的端口号,并且绑定的对象名称对于所有三个客户端也是不同的。
对于1st 2客户端,我得到了输出,并且为了解渴,我没有得到任何输出。只有"空指针异常"我正在客户端。在服务器端,我在所有3台服务器上都给了-Xms250m到-Xmx 20g。在客户端都有8 GB ram我给了-Xmx6g。
答案 0 :(得分:1)
您需要使用自定义的RMIRegistry端口才能在同一台计算机上运行两个或多个注册表实例。查看此完全正常工作的RMI服务器和客户端示例,您可以运行连接到同一远程对象实例的多个客户端。请记住同步服务实现的内部行为。
这是在服务器计算机上运行的远程服务接口和实现。
import java.rmi.*;
public interface CounterService extends Remote {
public void setValue(String value) throws RemoteException;
public String getValue() throws RemoteException;
}
- - - - - -
import java.rmi.*;
public class CounterServiceImpl implements CounterService {
private int callCount=0;
private String name;
private String value;
public CounterServiceImpl(String name) {
this.name=name;
this.value="";
}
public synchronized void setValue(String value) throws RemoteException {
callCount++;
this.value=value;
}
public synchronized String getValue() throws RemoteException {
callCount++;
return String.format("%s (name=%s, callcount=%d)", value, name, callCount);
}
}
这是RMI客户端和服务器实现。
import java.util.*;
import java.rmi.*;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.server.ExportException;
public class RMITest1Client {
private static Random randomInt = new Random();
public static int getRandomInt(int min, int max) {
int range = (max - min) + 1;
return randomInt.nextInt(range) + min;
}
public static void main(String[] args) throws Exception {
String rmiEndPoint = args[0];
String serviceName = args[1];
CounterService counter = (CounterService)Naming.lookup(rmiEndPoint+"/"+serviceName);
System.out.println("Connected to " + rmiEndPoint+"/"+serviceName);
for(int idx=0; idx<10; idx++) {
System.out.println("getValue="+counter.getValue());
Thread.sleep(getRandomInt(1, 5)*1000);
counter.setValue( "val"+getRandomInt(100, 999) );
Thread.sleep(getRandomInt(1, 5)*1000);
}
}
}
- - - - - -
import java.rmi.*;
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.server.ExportException;
public class RMITest1Server {
public static void main(String[] args) throws Exception {
// create the RMIregistry service
int port = Integer.parseInt(args[0]);
Registry registry;
try {
System.out.println("RMIRegistry on port " + port);
registry = LocateRegistry.createRegistry(port);
} catch (ExportException ex) {
// registry may already be created by another process,
// get reference to an existing registry instance.
System.out.println("Creating registry failed, try to connect an existing registry, ex="+ex.getMessage());
registry = LocateRegistry.getRegistry(port);
}
CounterService counter = new CounterServiceImpl("counter1");
UnicastRemoteObject.exportObject(counter, port);
registry.rebind("counter1", counter);
counter = new CounterServiceImpl("counter2");
UnicastRemoteObject.exportObject(counter, port);
registry.rebind("counter2", counter);
System.out.println("Running...");
Thread.sleep(30000);
// close registry objects
for(String serviceName : registry.list()) {
try {
System.out.println("RMIRegistry unbind " + serviceName);
Remote obj = (Remote)registry.lookup(serviceName);
UnicastRemoteObject.unexportObject(obj, true);
} catch (Exception ex) { }
try { registry.unbind(serviceName); } catch (Exception ex) { }
}
System.out.println("RMIRegistry closed");
System.exit(0); // mandatory if RMIRegistry was started in this JVM instance
}
}
以下是运行服务器和客户端的测试脚本。
**goServer.bat**
@SET /p port=Server port (2222, 3333, 0=exit):
@IF "0"=="%port%" GOTO :EOF
java -cp "./lib/*;" RMITest1Server %port%
pause
- - - - - -
**goClient.bat**
@SET /p port=Server port (2222, 3333, 0=exit):
@IF "0"=="%port%" GOTO :EOF
@SET /p service=Service index (1,2):
java -cp "./lib/*;" RMITest1Client rmi://127.0.0.1:%port% counter%service%
pause