????javaRMI

 前言:JavaRMI的使用并不麻烦,让我真正感兴趣的是stubs和skeletons,更让我感兴趣的是RMI框架如何让客户端感觉像在调用本地方法一样去使用远程对象的方法。(阅读本文建议先了解rmi的基本用法,可参考附件demo)

本篇文章重点关注以下问题:

  • 什么是stubs和skeletons对象?谁创建了他们?扮演什么角色?
  • 客户端如何找到服务端?如何知道服务端发布服务的端口?
  • 注册中心是否是必须的?什么作用?

1、回归本质需求

        首先忘记注册中心,最开始的使用场景是这样的:服务端Server发布服务,客户端Client需要使用到Server发布的服务(可以理解成api),Server继承了java.rmi.server.UnicastRemoteObject,问题在于Server和Client运行在不同的机器上面,而Client却想执行一个在远程机器上Server发布的方法。

        很容易想到,Rmi想解决上述问题肯定会涉及到Socket网络编程,因为Server运行在远程机器上,牵扯到具体实现有两个关键点:

  • 客户端Client如何从处理网络连接中解耦开来,从而专注于业务?
  • 客户端Client如何像调用本地方法一样来调用远程机器上的方法?

        上述问题就是stubs和skeletons存在的意义,正是stubs和skeletons的存在才能让客户端和服务器不需要处理网络相关的方法。stubs同样实现了和服务端同样的java.rmi.server.UnicastRemoteObject接口,这样当Client想调用Server上的方法时,就可以调用stubs上的相同的方法,但是stub上只有和网络相关的处理逻辑,并没有对应的业务处理逻辑。比如说Server上发布了一个add方法,则stub中也同样有一个add方法,但是stub上的这个add方法并不包含业务逻辑部分的实现,它仅仅包含如何连接到远程的skeleton,调用方法的详细信息、参数、返回值等。整个实现架构如下图所示:

 

         简言之,就是客户端Client和stub对话,stub和skeleton对话,skeleton和Server对话,Server执行真正的方法,饭后把结果原路返回。由图中也可以看出,Rmi的功能主要由四个部分组成:Client、stub、skeleton、Server。

2、Socket层详细信息

socket层通信的整个流程:

1.Server在远程机器上发布服务,并监听一个端口。这个端口是JVM或是OS在运行时随机选择的一个端口,可以说Server在远程机器的端口上发布服务。

2.Client调用Server上发布的方法。其实Client并不知道Server在哪,也并不知道Server在监听哪个端口,但是Client有stub,stub知道所有这些东西,这样Client就可以调用stub上他想调用的任何方法;

3、stub链接到Server监听的端口上并发送参数,过程如下:

       > Client连接到Server监听的端口;

       > Server收到请求并创建一个socket来处理这个链接;

       > Server继续监听到来的请求;

       > Client和Server使用双发商量的协议来传送参数和结果;(协议可以是JRMP或者 iiop)

4. 方法在远程Server上执行,并将执行结果返回给stub

5. stub返回结果给Client,就好像stub执行了这个方法一样。

 

但是,仔细揣摩上述过程,似乎仍有漏洞,第二点说stub知道Server在哪,stub知道Server监听的端口,但是Server发布服务的端口是随机的,stub如何知道Server?不知道Server的Ip和Port也就不可能创建一个知道一切的stub。这也引出RMIRegistry注册中心的存在价值。

3、RMIRegistry注册中心的作用

你可能感兴趣的:(java,rmi,Skeleton,stubs)