转型Java阵营没多久,就面对企业级的需求,所以大量的调研内容,“是什么系列”几乎都是针对javaEE领域的姿势,可见我最近是多么的充实啊~

这次记录一下关于RMI的科普知识,其实它比起之前的ThriftAvro来说,已经非常的轻量级了~~

RMI(Remote Method Invocation)是jdk1.1就已经存在的分布式应用解决方案,轻量简单是它最大的特点,广泛的应用在EJB中。如果我们的系统比较小,服务很少且很轻,并且不需要面向跨语言,那么RMI是一个比较理想的选择。

在另外的一些场景,例如跨语言平台的分布式应用,RMI就显得过于简陋了,这个时候可能就需要其它的同类技术了~

RMI是基于TCP协议的传递可序列化java对象字节数据的库,因此,在同等业务数据量的前提下,RMI的效率要高于基于SOAP规范的WebService。因此,RMI可以用在业务结构简单,要求实时性高的分布式应用中。

设计角度上,java采用三层结构来实现RMI:客户端、服务端、注册表,这是很常见的基于服务的架构。具体细节可以从下图看出:

客户端一方包含:

  • 桩(Stub):远程对象在客户端上的代理;
  • 远程引用层(Remote Reference Layer):解析并执行远程引用协议,完成了调用的方法与服务对应地址的转换;
  • 传输层(Transport):发送调用、传递远程方法参数、接受远程方法执行结果。

服务端一方包含:

  • 骨架(Skeleton):读取客户端传递的方法参数,调用服务器端的实际对象方法,并接受方法执行后的返回值;
  • 远程引用层(Remote Reference Layer):处理远程引用语法之后向骨架发送远程方法调用;
  • 传输层(Transport):监听客户端的入站连接,接受并转发调用到远程引用层。

注册表(Registry):以URL形式注册远程对象,并向客户端回复远程对象的引用。

在实际的应用中,客户端并没有真正的和服务端直接对话来进行远程调用,而是通过本地JVM的桩对象来进行的。

  1. 客户端从远程服务器的注册表中查询并获得远程对象引用,当进行远程调用时,客户端首先会与桩对象进行对话,而这个桩对象将远程方法所需的参数序列化后,传递给它下层的远程引用层。
  2. 桩对象与远程对象具有相同的接口和方法列表,当客户端调用远程对象时,实际是由相对应的桩对象代理完成的。远程引用层在将桩的本地引用转换为服务器上对象的远程引用后,再将调用传递给传输层,有传输层通过tcp协议发送调用。
  3. 在服务器端,传输层监听入站连接,它一旦接受到客户端远程调用后,就将这个引用转发给其上层的远程引用。
  4. 服务端的远程引用层将客户端发送的远程引用转化为本地虚拟机的引用后,再将请求传递给骨架。
  5. 骨架读取参数,将请求传递给服务器,最后由服务器进行实际的方法调用。
  6. 如果远程方法调用后有返回值,则服务器将这些结果又沿着骨架->远程引用层->传输层向下传递。
  7. 客户端的传输层接受到返回值后,又沿着传输层->远程引用层->桩向上传递,最后由桩来反序列化这些返回值,并将最终结果传递给客户端程序。

从这个流程上可以看出,java为我们隐藏了很多处理细节,开发者可以只关注业务细节。

关于RMI的例子,网上非常的多,包括上面的内容,出自这里