RMI底层实现详解

RMI底层实现详解什么是RPC?RPC调用流程什么是RMI ?创建服务端句柄创建客户端句柄接口约定RMI缺点总结第一次写博客,工作这么多年了,总是从别人的博客寻找答案,打算从现在开始每周坚持写一次博客,一是加深对某个知识点的理解,二是为了时不时回来翻一翻,回忆那些平时不常用到的知识。打算写RMI是因为有一次被问到如何自己实现一个RPC框架,当时就懵逼了,平时只知道使用,但是是怎么实现的还真不清...
摘要由CSDN通过智能技术生成

第一次写博客,工作这么多年了,总是从别人的博客寻找答案,打算从现在开始每周坚持写一次博客,一是加深对某个知识点的理解,二是为了时不时回来翻一翻,回忆那些平时不常用到的知识。

打算写RMI是因为有一次被问到如何自己实现一个RPC框架,当时就懵逼了,平时只知道使用,但是是怎么实现的还真不清楚。自己工作中远程方法调用用的是dubbo,dubbo的源码也看过,但是dubbo包含的功能很多,我还没很好的理解dubbo的设计思想,所以RMI相对简单一些,虽然项目中没有用到,但是可以透过RMI去理解一个RPC的实现思路。

什么是RPC?

RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。

这段话摘自百度百科,它主要表达了3个意思

  1. RPC 是通过网络调用的 (这个好理解)
  2. RPC 封装了底层网络传输细节 ,我们不需要知道底层是通过什么协议转输数据的(比如TCP或者UDP,或者是应用层上的HTTP协议,又或者是自定义的私有协议),并且不用知道数据以什么格式传输的(比如是jdk的系列化流,或者json,xml)。
  3. RPC 是一种C/S模式 ,说明底层有一对socket和serverSocket。

RPC调用流程

借用百科的图:

图一

图1展示了一个RPC调用的流程图,其中看到,客户机和服务器上各自有一个客户句柄和服务句柄,客户端程序通过客户句柄调用远程服务,服务端程序通过服务句柄接收客户端的调用请求。

所以要实现RPC,关键在于如何实现这两个句柄,如何获取句柄?

什么是RMI ?

The Java Remote Method Invocation (RMI) system allows an object running in one Java virtual machine to invoke methods on an object running in another Java virtual machine. RMI provides for remote communication between programs written in the Java programming language.

摘自官网的解释,翻译过来大意是:
RMI能够使运行在一个JVM上的java程序调用运行在另一个JVM上的java方法。RMI实现就是Java版的一个RPC实现,但是只支持java,不能跨语言。接下来主要讲的是以1.8版本及以上的RMI实现。

接着盗图
工作原理
工作原理
上图的stub(不是sub->stub,错别字)和skeleton分别就是代表RPC调用原理的客户句柄(stub),服务句柄(skeleton),stub翻译叫存根,实际上stub和skeleton可以都理解成stub,只是工作在不同的主机上代理,一个代理客户端发起远程调用,一个代理服务端接收调用请求并返回结果。这里要说明的是,1.8之后stub和skeleton已经由RemoteObject代替,并且stub和skeleton的实现方式已经被标注为废弃,以动态代理的方式生成RemoteObject对像取而代之。不过他们从功能的角度看 一样的,只是实现方式不一样。

时序图
在这里插入图片描述

为了方便讲述,先举一个RMI调用的具体例子,代码来自官网的demo
远程接口定义:

package compute;

import java.rmi.Remote;
import java.rmi.RemoteException;
/**
 * 远程接口,接收客户端传送来的task任务并处理任务,返回结果给客户端
 * @author luyang
 */
public interface Compute extends Remote {
    <T> T executeTask(Task<T> t) throws RemoteException;
}


package compute;
/**
 * 任务接口
 * @author luyang
 * @param <T>
 */
public interface Task<T> {
    T execute();
}
package client;

import compute.Task;
import java.io.Serializable;
import java.math.BigDecimal;
/**
 * 计算圆周率的任务实现
 
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值