Java APi 之 RMI远程方法调用
一、什么是RPC
RPC全称是remote procedure call,即远程过程调用。它是一种协议,用于从远程计算机上请求服务。
例如有两台服务器A和B,A上的应用想要调用B上应用的方法,但是他们在不同的服务器,所以不能通过内存调用的方式,所以我们理所当然地去考虑通过网络来实现函数调用。RPC也就是能够实现A上的应用能够直接调用B上应用的方法的协议。
注:RPC和HTTP的不同点主要是在于针对使用场景而形成的不同特性,RPC协议主要应用于服务器的内部,也针对服务而形成如错误重试、服务发现等特性。
二、什么是RMI
RMI全称remote method invocation,即远程方法调用,是Java对RPC的一种客户端/服务端的实现,基于一个注册表Registry,如图
服务端创建并发布远程对象,注册表处理远程对象的映射地址;客户端通过映射地址从注册表获取远程对象,调用相应的方法。
三、RMI使用步骤
1、定义远程对象接口
2、实现远程对象
3、实现服务端
4、实现客户端
四、代码示例
定义远程对象接口Hello
import java.rmi.Remote; import java.rmi.RemoteException; /** * 远程对象接口定义 * * @author lay * @date 2018/8/29 13:23 */ public interface Hello extends Remote { /** * sayHello方法定义 * * @return * @throws RemoteException */ String sayHello() throws RemoteException; }
实现服务端,这里包括实现远程对象,发布和注册映射
import java.rmi.AlreadyBoundException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import java.rmi.server.UnicastRemoteObject; /** * RMI服务端 * * @author lay * @date 2018/8/29 13:24 */ public class Server implements Hello { /** * 实现远程接口方法 * * @return 字符串 * @throws RemoteException */ @Override public String sayHello() throws RemoteException { return "hello RMI"; } public static void main(String[] args) throws RemoteException, AlreadyBoundException { // 获取远程接口的远程对象 Server server = new Server(); // 发布远程对象到RMI Hello hello = (Hello) UnicastRemoteObject.exportObject(server, 8080); // 获取注册表 Registry registry = LocateRegistry.createRegistry(8080); // 绑定映射地址 registry.bind("hello", hello); System.out.printf("服务端启动成功"); } }
客户端实现
import java.rmi.NotBoundException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; /** * RMI客户端 * * @author lay * @date 2018/8/29 13:33 */ public class Client { public static void main(String[] args) throws RemoteException, NotBoundException { // 获取注册表 Registry registry = LocateRegistry.getRegistry(8080); // 查找远程对象 Hello hello = (Hello) registry.lookup("hello"); // 调用方法 String content = hello.sayHello(); System.out.printf("content:" + content); } }
启动服务端,客户端调用的输出结果为:
content:hello RMI
参考文章:
https://docs.oracle.com/javase/7/docs/technotes/guides/rmi/hello/hello-world.html#register