RMI = Remote Method Invocation, 远程方法调用机制: 允许一个JVM对象调用另一个JVM对象方法
这种机制特别适合分布式应用, 比如JMeter的分布式压测
1. 架构图
- RMI registry, 命名空间, 供server注册
- RMI server, 具体的实现, 被调用的对象
- RMI client, 从registry的命名空间中查找注册的方法, 实现远程调用
2. 样例
角色之前的关系如下, 代码逻辑大体一致
image.png
2.1. 定义远程调用接口
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* 定义Adder接口, 继承Remote对象
*/
public interface Adder extends Remote {
int add(int x, int y) throws RemoteException;
}
2.2. Server实现
启动server端程序, 可以发现监听端口1099, 8801 (二者进程号一致)
image.pngimport java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
/**
* 1. 实现Adder接口
* 2. 向registry注册
*/
public class AdderServer implements Adder {
@Override
public int add(int x, int y) throws RemoteException {
return x + y;
}
public static void main(String[] args) {
try {
Adder adder = new AdderServer();
// Server服务监听8801端口, 等待client请求
Remote adderStub = UnicastRemoteObject.exportObject(adder, 8801);
// registry监听端口1099, 注册server方法
Registry registry = LocateRegistry.createRegistry(1099);
registry.rebind("Adder", adderStub);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
2.3. Client实现
- 通过ip + port连接registry服务
- 在registry上查找server注册的方法
- 然后直接调用
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
public static void main(String[] args) {
try {
Registry registry = LocateRegistry.getRegistry("localhost", 1099);
Adder adder = (Adder) registry.lookup("Adder");
int result = adder.add(13, 14);
System.out.println(result);
} catch (RemoteException | NotBoundException e) {
e.printStackTrace();
}
}
}
网友评论