问题
I am trying to run 3 RMI server on Single (96 Ram) Machine. From three different machine clients are calling, but for three clients I have given 3 different port numbers and binded object name are also different for all three client.
For 1st 2 client I got the output and for thirst one I am not getting any output. Only "Null Pointer exception" I am getting on client side. On Server side I have given -Xms250m to -Xmx 20g on all 3 server. On client all have 8 GB ram I have given -Xmx6g.
回答1:
You need to use a customized RMIRegistry port to have two or more registry instances run in a same machine. See this fully working RMI Server and Client example, you can run multiple clients connecting to the same remote object instance. Remember to synchronize internal behaviour of the service implementation.
Here is a remote service interface and implementation run on server machine.
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);
}
}
Here is a RMI client and server implementation.
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
}
}
Here are test scripts to run server and client.
**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
来源:https://stackoverflow.com/questions/38438070/one-binded-rmi-name-can-be-used-by-multiple-client