RPC架构分析全称为:remote procedure call,翻译过来就是远程过程调用,我们可以借用RPC的特性,也就是RPC可以实现项本地调用一样调用远程服务,它就是一种进程之间的通信方式
传统调用:
RPC调用:
RMI机制 相关介绍一个完整的RPC架构里面主要是包含了四个核心组件:Client、Client Stub、Server和Server Stub,其中这个Stud可以理解为是存根
Client客户端:服务的调用方Client Stub客户端存根:存放服务端地址信息,再将客户端的请求参数打包成网络信息,然后通过网络远程发送给服务方Server服务端:服务提供者Server Stub:接收客户端发送过来的信息,将消息解包,并调用本地的方法 时序图
分析一下:
client以本地调用的方式调用服务client stub接收到调用请求后,负责将方法、参数等组装成能够进行网络传输的消息体,也就是序列化为二进制进行传输client通过socket将消息发送到服务端server stub收到消息后进行解码操作,将消息对象反序列化server stub根据解码结果调用本地的服务服务处理本地服务执行并将处理结果返回给server stubserver stub将结果打包成消息,序列化server通过socket将消息发送到客户端client stub接收到结果消息,并进行解码,也就是反序列化client就收到了最终的结果数据
其中2345789、10是RPC主要做的事情,剩下的1、6、11就属于网络传输了,对于RPC框架来说,最核心的就是通讯和序列化
代码体验Java RMI,也就是远程方法调用,是一种实现远程过程调用的API,特性是能够直接传输序列化后的java对象,它主要依赖于JVM,所以它只能支持两个JVM之间的调用
使用代码体验一下RMI的运行机制
模拟需求:
服务端提供一个查询订单的方法客户端调用接口,返回订单信息全程使用RMI来实现远程通信调用 订单实体类
必须实现序列化
public class Order implements Serializable { private Integer id; private String title; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }订单接口必须继承Remote和方法必须抛出RemoteException异常
public interface IOrderService extends Remote { Order getById(int id) throws RemoteException; }接口实现类public class OrderServiceImpl extends UnicastRemoteObject implements IOrderService{ MapRMI服务端public class RMIServer { public static void main(String[] args) { try { //注册实例,绑定端口 Registry registry=LocateRegistry.createRegistry(9999); //创建远程对象 IOrderService iOrderService = new OrderServiceImpl(); //将远程对象注册到RMI服务器上,也就是注册表上 registry.rebind("orderService",iOrderService); System.out.println("============RMI服务端启动成功=============="); } catch (RemoteException e) { e.printStackTrace(); } } }RMI客户端public class RMIClient { public static void main(String[] args) throws RemoteException, NotBoundException { //根据端口获取实例 Registry registry=LocateRegistry.getRegistry(9999); //通过实例查找远程对象 IOrderService orderService=(IOrderService)registry.lookup("orderService"); //调用方法查询订单 Order order=orderService.getById(1); System.out.println("=====================>"+order.getId()+"==============>"+order.getTitle()); } }先运行服务端,再运行客户端,会打印如下日志:



