RPC 通信和 RMI 区别
RPC(Remote Procedure Call Protocol)远程过程调用协议,通过网络从远程计算机上请求调用某种服务。
一个RPC框架包含的要素
RMI (Remote Method Invocation) 远程方法调用。能够让在客户端Java虚拟机上的对象像调用本地对象一样调用服务端java 虚拟机中的对象上的方法。是 Java 领域创建分布式应用的技术基石。后续的 EJB 技术,以及现代的分布式服务框架,其中的基本理念依旧是 Java RMI 的延续。使用的是JRMP(Java Remote Messaging Protocol)
在 RMI 调用中,有以下几个核心的概念:
- 通过接口进行远程调用
- 通过客户端的 Stub 对象和服务端的 Skeleton 对象的帮助将远程调用伪装成本地调用
- 通过 RMI 注册服务完成服务的注册和发现
RPC与RMI的区别
1:方法调用方式不同:
RMI中是通过在客户端的Stub对象作为远程接口进行远程方法的调用。每个远程方法都具有方法签名。如果一个方法在服务器上执行,但是没有相匹配的签名被添加到这个远程接口(stub)上,那么这个新方法就不能被RMI客户方所调用。
RPC中是通过网络服务协议向远程主机发送请求,请求包含了一个参数集和一个文本值,通常形成“classname.methodname(参数集)”的形式。RPC远程主机就去搜索与之相匹配的类和方法,找到后就执行方法并把结果编码,通过网络协议发回。
2:适用语言范围不同:
RMI只用于Java;
RPC是网络服务协议,与操作系统和语言无关。
3:调用结果的返回形式不同:
Java是面向对象的,所以RMI的调用结果可以是对象类型或者基本数据类型;
RMI的结果统一由外部数据表示 (External Data Representation, XDR) 语言表示,这种语言抽象了字节序类和数据类型结构之间的差异。
Java RMI 工作原理
一个典型的 RMI 调用如下图所示:
- 服务端向 RMI 注册服务绑定自己的地址;register
- 客户端通过 RMI 注册服务获取目标地址;subscribe+notify
- 客户端调用本地的 Stub 对象上的方法,和调用本地对象上的方法一致;
- 本地存根对象将调用信息打包,通过网络发送到服务端;
- 服务端的 Skeleton 对象收到网络请求之后,将调用信息解包;
- 然后找到真正的服务对象发起调用,并将返回结果打包通过网络发送回客户端。
现实中不直接使用RMI作为远程调用的原因:
- 底层是BIO、而不是NIO
- 其只能用于Java,不能扩展其他语言
- 底层序列化使用JDK的序列化机制,效率不高
其注册中心是单点的,挂了的话整个系统不可用