参考 分布式架构基础:Java RMI详解
GitHub: https://github.com/jayknoxqu/rmi-example
RMI简介
Java RMI,即 远程方法调用(Remote Method Invocation),一种用于实现远程过程调用(RPC)(Remote procedure call)的Java API, 能直接传输序列化后的Java对象和分布式垃圾收集。它的实现依赖于Java虚拟机(JVM),因此它仅支持从一个JVM到另一个JVM的调用。
(1) 直接使用Registry实现rmi
Registry(注册表)是放置所有服务器对象的命名空间。
每次服务端创建一个对象时,它都会使用bind()或rebind()方法注册该对象。
这些是使用称为绑定名称的唯一名称注册的。
要调用远程对象,客户端需要该对象的引用,如(HelloRegistryFacade)。
即通过服务端绑定的名称(HelloRegistry)从注册表中获取对象(lookup()方法)。
HelloRegistryFacade
package com.example.rmi.registry;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface HelloRegistryFacade extends Remote {
String helloWorld(String name) throws RemoteException;
}
HelloRegistryFacadeImpl
package com.example.rmi.registry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class HelloRegistryFacadeImpl extends UnicastRemoteObject implements HelloRegistryFacade {
public HelloRegistryFacadeImpl() throws RemoteException {
super();
}
@Override
public String helloWorld(String name) {
return "[Naming] 你好! " + name;
}
}
RegistryService
package com.example.rmi.registry;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class RegistryService {
public static void main(String[] args) {
try {
// 本地主机上的远程对象注册表Registry的实例,默认端口1099
Registry registry = LocateRegistry.createRegistry(1099);
// 创建一个远程对象
HelloRegistryFacade hello = new HelloRegistryFacadeImpl();
// 把远程对象注册到RMI注册服务器上,并命名为HelloRegistry
registry.rebind("HelloRegistry", hello);
System.out.println("======= 启动RMI服务成功! =======");
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
RegistryClient
package com.example.rmi.registry;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class RegistryClient {
public static void main(String[] args) {
try {
Registry registry = LocateRegistry.getRegistry(1099);
HelloRegistryFacade hello = (HelloRegistryFacade) registry.lookup("HelloRegistry");
String response = hello.helloWorld("ZhenJin");
System.out.println("=======> " + response + " <=======");
} catch (NotBoundException | RemoteException e) {
e.printStackTrace();
}
}
}
(2) 使用Naming方法实现rmi
Naming其实是对Registry的一个封装
代码参照 GitHub
Zookeeper(注册中心)实现rmi
简单来说就是把Registry(注册表)信息放在zk上保存,需要请求的时候,先到zk上查询
图解
注册github代码,client链接时会报错,说路径不存在
需要自己手动通过zk_client.bat 创建目录
#启动之前 需要手动在 zookeeper中添加一个根路径
ls / 列出根路径的所有路径
create /registry aa 在跟路径创建 /registry 值是 aa
get /registry 获取 /registry 的值 aa