分布式(基础)-RMI的原理

简介: 分布式(基础)-RMI的原理

RMI的原理

RMI执行过程图如下:


1.1、Remote Service和注册表(Locate Registry)还有Remote Client都可以是不同的jvm。然后注册的时候都是把服务注册到Naming里面去,每一个Naming都会有有一个Remote Stub就是服务端实现接口生成的代理类对象。

Locate Registry:类似于注册中心,就是一个公共的区间。绑定的东西是绑定到注册中心上的,调用的时候也是从Locate Registry里拿的。

1.2、然后会反向生成Remote Skeleton骨架,然后通过远程的引用层再到传送层,通过Socket进行通信。

1.3、Remote Service和Remote Client是通过远程机器协议(JRMP)进行通信的。

1.4、Remote Client去Naming去查找,通过RMI的协议看能否找到对应的代理对象,如果有的话,就会把这个代理对象给返回出来。

1.5、再到Remote Client的远程引用层再到Remote Client的传送层 ,从而和Remote Service实现透明化的通信。

2、远程方法调用过程:


①:客户端通过接口来发送一个请求。

②:接口又通过java中的jvm,来生成 一个stub的对象,相当于是一个根对象,就是一个代理。

③:代理将所有的网络通信通过③拿到④这边能够解析的编码格式,Skeleton也是服务端发布服务的代理类,这个代理类的作用是真正去调用服务端的接口的实现类中对应的方法。

上面用了两个代理,一个是代理客户端的,一个是代理服务端的,不管哪种代理,都是用socket来实现远程通信的。

④:它会把Skeleton骨架,刚 从客户端发过来的来进行解码,解码为服务端所调用方法所用的参数及其对应的类型。

⑤:然后去服务端去调用。

⑥:把返回的结果再返回给Skeleton。

⑦:Skeleton按照他们规定好的方式来包装数据。

⑧:然后发送到客户端的代理对象中。

⑨:客户端把数据解码。

⑩:返回到客户端。

2.1、区分下TCP和RPC还有RMI:

TCP:传输控制层协议。rpc:远程过程调用的框架。RMI:远程调用接口。

3、源码分析RMI如何去做通信的?

3.1、服务端:有一个createRegistry的方法

在这个方法里面有一个接口对应的实现类RegistryImpl,然后把这个port放入到了构造函数里面去

  1.   public static Registry createRegistry(int port) throws RemoteException {
  2.        return new RegistryImpl(port);
  3.    }


  1.    public RegistryImpl(final int var1) throws RemoteException {
  2.        this.bindings = new Hashtable(101);
  3.        //如果这个接口是1099并且是系统安全的
  4.        if (var1 == 1099 && System.getSecurityManager() != null) {
  5.            try {
  6.        //进行权限的验证
  7.                AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
  8.                    public Void run() throws RemoteException {
  9.                        LiveRef var1x = new LiveRef(RegistryImpl.id, var1);
  10.                        RegistryImpl.this.setup(new UnicastServerRef(var1x, (var0) -> {
  11.                            return RegistryImpl.registryFilter(var0);
  12.                        }));
  13.                        return null;
  14.                    }
  15.                }, (AccessControlContext)null, new SocketPermission("localhost:" + var1, "listen,accept"));
  16.            } catch (PrivilegedActionException var3) {
  17.                throw (RemoteException)var3.getException();
  18.            }
  19.        } else {
  20.           //如果不在1099端口的话这里创建一个LiveRef的引用类,这个引用类是可以支持克隆的。
  21.           //是可以支持对象拷贝的,一般是做浅拷贝的,不是深拷贝。
  22.            LiveRef var2 = new LiveRef(id, var1);
  23.            this.setup(new UnicastServerRef(var2, RegistryImpl::registryFilter));
  24.        }

  25.    }

在exportObject这个方法中

  1.   public Remote exportObject(Remote var1, Object var2, boolean var3) throws RemoteException {
  2.        Class var4 = var1.getClass();

  3.        Remote var5;
  4.        try {
  5.         //通过客户端引用的接口生成一个代理对象var5
  6.         //由于自己写的接口的代码是继承了Remote的
  7.         //这也就是在服务端去调用不能改变路径的原因
  8.            var5 = Util.createProxy(var4, this.getClientRef(), this.forceStubUse);
  9.        } catch (IllegalArgumentException var7) {
  10.            throw new ExportException("remote object implements illegal remote interface", var7);
  11.        }
  12.       //判断生成的代理对象是否是一个根对象
  13.        if (var5 instanceof RemoteStub) {
  14.          //是这个对象的话直接设置到skeleton里面
  15.            this.setSkeleton(var1);
  16.        }
  17. //构建一个新的目标对象
  18.        Target var6 = new Target(var1, this, var5, this.ref.getObjID(), var3);
  19.  //新的对象又会去执行exportObject的操作
  20.        this.ref.exportObject(var6);
  21.        this.hashToMethod_Map = (Map)hashToMethod_Maps.get(var4);
  22.        return var5;
  23.    }

在Naming.bind方法中:这个方法是对端口的绑定,得到Registry注册的列表 ,然后再把其放入到注册中心里面去。

  1.   public static void bind(String name, Remote obj)
  2.        throws AlreadyBoundException,
  3.            java.net.MalformedURLException,
  4.            RemoteException
  5.    {
  6.        ParsedNamingURL parsed = parseURL(name);
  7.        Registry registry = getRegistry(parsed);

  8.        if (obj == null)
  9.            throw new NullPointerException("cannot bind to null");

  10.        registry.bind(parsed.name, obj);
  11.    }

RMI的缺点:①、不是跨语言的。②、灵活性太低了。

在spring很老的版本中就封装了RMI。


未完待续!!如果哪里写的有问题,请指出。xxxxxxxxxxxxxxxxxxxx,谢谢。

相关文章
|
8月前
|
设计模式 安全 Java
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
【分布式技术专题】「Tomcat技术专题」 探索Tomcat技术架构设计模式的奥秘(Server和Service组件原理分析)
122 0
|
8月前
|
存储 分布式计算 Hadoop
Hadoop【基础知识 01】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)
【4月更文挑战第3天】Hadoop【基础知识 01】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)
274 3
|
2月前
|
存储 Dubbo Java
分布式 RPC 底层原理详解,看这篇就够了!
本文详解分布式RPC的底层原理与系统设计,大厂面试高频,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
分布式 RPC 底层原理详解,看这篇就够了!
|
1月前
|
机器学习/深度学习 存储 运维
分布式机器学习系统:设计原理、优化策略与实践经验
本文详细探讨了分布式机器学习系统的发展现状与挑战,重点分析了数据并行、模型并行等核心训练范式,以及参数服务器、优化器等关键组件的设计与实现。文章还深入讨论了混合精度训练、梯度累积、ZeRO优化器等高级特性,旨在提供一套全面的技术解决方案,以应对超大规模模型训练中的计算、存储及通信挑战。
91 4
|
3月前
|
分布式计算 Hadoop 网络安全
Hadoop-08-HDFS集群 基础知识 命令行上机实操 hadoop fs 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
Hadoop-08-HDFS集群 基础知识 命令行上机实操 hadoop fs 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
58 1
|
3月前
|
存储 机器学习/深度学习 缓存
Hadoop-07-HDFS集群 基础知识 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
Hadoop-07-HDFS集群 基础知识 分布式文件系统 读写原理 读流程与写流程 基本语法上传下载拷贝移动文件
73 1
|
8月前
|
存储 分布式计算 监控
Hadoop【基础知识 01+02】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
【4月更文挑战第3天】【分布式文件系统HDFS设计原理+特点+存储原理】(部分图片来源于网络)【分布式计算框架MapReduce核心概念+编程模型+combiner&partitioner+词频统计案例解析与进阶+作业的生命周期】(图片来源于网络)
370 2
|
3月前
|
存储 缓存 数据处理
深度解析:Hologres分布式存储引擎设计原理及其优化策略
【10月更文挑战第9天】在大数据时代,数据的规模和复杂性不断增加,这对数据库系统提出了更高的要求。传统的单机数据库难以应对海量数据处理的需求,而分布式数据库通过水平扩展提供了更好的解决方案。阿里云推出的Hologres是一个实时交互式分析服务,它结合了OLAP(在线分析处理)与OLTP(在线事务处理)的优势,能够在大规模数据集上提供低延迟的数据查询能力。本文将深入探讨Hologres分布式存储引擎的设计原理,并介绍一些关键的优化策略。
202 0
|
4月前
|
Dubbo Java 应用服务中间件
分布式(基础)-RMI简单的应用
分布式(基础)-RMI简单的应用
|
6月前
|
NoSQL Redis 数据库