分布式消息通讯框架RMI原理分析

什么是RPCjava

  • 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 源码分析安全

  • 远程对象发布

远程引用层服务器

一步步解读源码网络

  • 发布远程对象
    • 看到上面的类图能够知道,这个地方会发布两个远程对象,一个是RegistryImpl、另一个是咱们本身写的RMI 实现类对象

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

  • 有一个问题为何断点进去的时候,会重复接收到多个请求
    • 这是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,而且启动了一条线程等待客户端的请求。

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

  • 看源码要看到什么程度:“看到你以为你能说服本身就能够了”
相关文章
相关标签/搜索