博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
分布式消息通信框架RMI原理分析
阅读量:5730 次
发布时间:2019-06-18

本文共 1914 字,大约阅读时间需要 6 分钟。

hot3.png

什么是RPC

  • RPC(Remote Procedure Call,远程过程调用)
  • 一般用来实现部署在不同机器上系统之间方法调用
    • 使得程序能够像访问本地系统资源一样,通过网络传输去访问远端系统资源;(!!!)
    • 对于客户端来说, 传输层使用什么协议,序列化、反序列化都是透明的

了解 Java RMI

  • RMI 全称是remote method invocation – 远程方法调用,
  • 一种用于远程过程调用的应用程序编程接口,是纯java 的网络分布式应用系统的核心解决方案之一。
  • RMI 目前使用Java 远程消息交换协议JRMP(Java Remote Messageing Protocol) 进行通信,
  • 由于JRMP 是专为Java对象制定的,是分布式应用系统的百分之百纯java 解决方案,
  • 用Java RMI 开发的应用系统可以部署在任何支持JRE的平台上

Java RMI 代码实践

  • 远程对象必须实现UnicastRemoteObject
  • 这样才能保证客户端访问获得远程对象时,该远程对象把自身的一个拷贝Socket 形式传输给客户端
  • 客户端获得的拷贝称为“stub” ,
  • 而服务器端本身已经存在的远程对象成为“skeleton”,
  • 此时客户端的stub 是客户端的一个代理,用于与服务器端进行通信
  • 而skeleton 是服务端的一个代理
  • 用于接收客户端的请求之后调用远程方法来响应客户端的请求

Java RMI 源码分析

  • 远程对象发布

b3ce8ab6429188dfc7e460cbe310aca7f9c.jpg

远程引用层

67aabda38846f443cbf33eb16805bf39da0.jpg

一步步解读源码

  • 发布远程对象
    • 看到上面的类图可以知道,这个地方会发布两个远程对象,一个是RegistryImpl、另外一个是我们自己写的RMI 实现类对象

daf0949b3c93409dd0811c55dd393714cee.jpg

83634c87573f10204b923f6a0485c7097c3.jpg

LocateRegistry.createRegistry(1099);
  • 如果服务端指定的端口是1099 并且系统开启了安全管理器,那么就可以在限定的权限集内绕过系统的安全校验。
  • 这里纯粹是为了提高效率, 真正的逻辑在this.setup(newUnicastServerRef())这个方法里面

260ae32bee56f59bd113d160877f5f8e1cb.jpg

  • 有一个问题为什么断点进去的时候,会重复接收到多个请求
    • 这是TCP协议特性
    • TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。
    • 然后接收端实体对已成功收到的包发回一个相应的确认(ACK);
    • 如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。
    • TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。
  • 这个Target 对象基本上包含了全部的信息,等待TCP 调用。
    • 包装实际对象,并将其曝露在TCP端口上,等待客户端调用
    • 用skeleton、stub、UnicastServerRef 对象、id 和一个boolean 值构造了一个Target 对象
  • LiveRef 与TCP 通信的类
  • RegistryImpl extends RemoteServer implements Registry
    • Skeleton
    • private Hashtable<String, Remote> bindings = new Hashtable(101);
    • 这个bindings 绑定服务(注册中心)
    • Naming.rebind("rmi://127.0.0.1/Hello",helloService); //注册中心 key - value
  • RegistryImpl_Stub
    • stub
  • LocateRegistry
  • UnicastServerRef
    • 内部引用了LiveRef
  • UnicastRemoteObject
    • 字面意思(单播远程对象)
  • RemoteRef
  • Remote
  • TCPTransport
    • 调用TCPTransport 的listen()方法,listen()方法创建了一个ServerSocket,并且启动了一条线程等待客户端的请求。

b465ac2f9bbed049ee6400642aab139e8c3.jpg

  • Stub和Skeleton:
    • 这两个的身份是一致的,都是作为代理的存在。
    • 客户端的称作Stub,服务端的称作Skeleton。
    • 要做到对程序员屏蔽远程方法调用的细节,这两个代理是必不可少的,包括网络连接等细节。
  • Registry:顾名思义,可以认为Registry是一个“注册重心”,提供了服务名到服务的映射。
    • 如果没有它,意味着客户端需要记住每个服务所在的端口号,这种设计显然是不优雅的。

bbca1988f6ac357406c83d4468a5bfb039f.jpg

122915d21c723f1d2bf4f34276b55f9deb1.jpg

965b11197d4557052038ac76ec441d30b44.jpg

  • 看源码要看到什么程度:“看到你觉得你能说服自己就可以了”

转载于:https://my.oschina.net/u/3847203/blog/2875662

你可能感兴趣的文章
QPS从0到4000请求每秒,谈达达后台架构演化之路
查看>>
我的友情链接
查看>>
Spring源码解析(八)——实例创建(下)
查看>>
【Android】Android开发之著名框架ButterKnife的使用详解,butterknife8.1.0版本的使用方法...
查看>>
Windows Server 2012 最详细的安装教程
查看>>
nginx nginx_upstream_check_module nginx-sticky-module 安装
查看>>
DNS显性+隐性URL转发原理
查看>>
Ubuntu系统redis安装部署入门
查看>>
我的友情链接
查看>>
使用Azure Storage进行静态Web托管
查看>>
网易有道 IP地址、手机号码归属地和身份证 查询接口API
查看>>
XT [2011-06-25]更新到0.41版本
查看>>
Linux服务篇之六:源码包构建LAMP架构配置
查看>>
鼠标停留在GridView某一行时行的颜色改变
查看>>
【v2.x OGE教程 14】控件使用
查看>>
nginx利用第三方模块nginx_upstream_check_module来检查后端服务器的健康情况
查看>>
系列3:WAS Liberty Profile hello mysql jdbc
查看>>
BFC 神奇背后的原理
查看>>
动态ACL(1)
查看>>
基础知识:python模块的导入
查看>>