美文网首页后端小树林
分布式对象之客户\服务器角色以及RMI初探

分布式对象之客户\服务器角色以及RMI初探

作者: 奔跑的蛙牛 | 来源:发表于2018-08-26 20:49 被阅读0次

    无所不在的java对象

    程序员希望通过无所不在的java对象来作为所有问题的解决之道,思想就是通过网络请求相互协作。我可以调用一个远程对象帮我得到我所要的信息,并作为响应的一部分返回

    引出客户与服务器角色

    分布式编程的基本思想就是:客户端请求服务器,服务器根据请求处理得到客户端需要的信息返回


    对象传递在各端

    使用代理的远程方法调用

    image.png

    java的远程方法调用

    • RMI,java远程方法调用技术,支持java分布式对象之间的调用

    远程方法调用

    分布式计算的关键就是远程方法调用
    实现的点

    1. 参数必须以某种方式传递到另一台机器上
    2. 服务器得到通知去定位远程对象
    3. 将响应值返回

    存根

    客户代码在远程对象调用一个远程方法实际上调用的是一个代理对象的普通方法,称此对象为存根

    Warehouse centralHouse = get sub object;
    double price = centralWarehouse.getPrice("xxx")
    

    存根一般位于客户端,他知道如何通过网路与服务器进行交互。存根会将参数打包称一组字节
    对参数编码的过程称之为参数编组,参数编组的目的将参数转化为虚拟机传递的合适格式。RMI是通过序列化进行编码

    • 客户端构造存根的信息块
    1. 被使用远程对象的标识符
    2. 被调用方法的描述
    3. 被编码的参数
    • 服务端接收后的动作
    1. 定位调用的远程对象
    2. 调用所需的方法,并传递客户端提供的参数
    3. 捕获返回值或调用产生的异常
    4. 将返回值编组打包返回给客户端存根

    以上方法的信息流图


    参数编组

    RMI编程模型

    建立一个简单的实例--->远程对象表示为一个仓库,客户端通过远程仓库获取产品价格

    1. 接口实现

    接口描述远程对象所实现的服务

    // wareHouse.java
    import java.rmi.*
    public interface WareHouse extends Remote{
      double getPrice(string desciption) throws RemoteException;
    }
    

    服务器提供的类

    // WarehouseImpl.java
    import java.rmi.*
    import java.rmi.server.*
    import java.util.*
    
    public class WarehouseImpl extends UnicastRemoteObject implements WareHouse{
      private Map<String,Double> prices;
      public WarehouseImpl throws RemoteException{
        prices = new HashMap<>();
        prices.put("1xx",23.1);
        prices.put("2xx",23.4);
      }
      public double getPrice(String description) throws RemoteException{
        Double prices = prices.get(description);
        return prices?0:prices;
      }
    }
    

    客户端RMI注册表

    要调用远程对象,首先需要一个本地的存根对象此时需要调用远程方法获取第一个存根对象。服务器通过自居注册服务注册至少一个远程对象

    // 下面代码构造并实现一个对象
    import java.rmi.*
    import java.naming.*
    public class WarehouseServer {
      public static void main(String args[]){
        WarehouseImpl centralHouse = new WarehouseImpl();
        Context nameContext = new InitialContext();
        namingContext.bind("rmi:centrl_wareHouse",centralHouse);
      }
    }
    

    客户端通过下面方式获得存根

    String url = "rmi://xx.xx.com/centrl_wareHouse";
    Warehouse centralWareHouse = (Warehouse) nameingContext.lookup(url);

    获取价钱流程图

    image.png

    相关文章

      网友评论

        本文标题:分布式对象之客户\服务器角色以及RMI初探

        本文链接:https://www.haomeiwen.com/subject/rigoiftx.html