分布式编程技术的基本思想:客户计算机产生一个请求,然后将这个请求通过网络发送到服务器。服务器处理这个请求,并发送回一个针对该客户端的响应,供客户端进行分析。
客户端和服务端之间用代理进行通讯,客户端调用代理进行常规的方法调用,而客户端代理与服务端代理进行联系,服务端代理以常规方式调用服务器对象上的方法。
代理之间通信技术:
    1.RMI,Java的远程方法调用技术,支持Java的分布式对象之间的方法调用。
    2.CORBA,通过对象请求代理架构,支持任何编程语言编写的对象之间的方法调用。CORBA使用Internet Inter-ORB协议(IIOP)支持对象间通信。
    3.Web服务架构是一个协议集,有时统一描述为WS-*。独立于编程语言,使用基于XML的通信格式。用于传输对象的格式则是简单对象访问协议(SOAP)。
    若互相通信的程序都是由Java实现的,那么CORBA与WS-*的通用性和复杂性统统是不需要的。远程方法调用(RMI)专门针对Java应用之间的通信。
分布式计算的关键是远程方法调用。在一台机器(称为客户端)上的某些代码希望调用在另一台机器(远程对象)上的某个对象的一个方法。要实现这点,方法的参数必须以某种方式传递到另一台机器上,而服务器必须得到通知,去定位远程对象并执行要调用的方法,并且必须将返回值传递回去。
存根和参数编组
当客户代码要在远程对象上调用一个远程方法时,实际上调用的是代理对象上的一个普通方法,此代理对象称为存根(stub)。
存根位于客户端机器上,而非服务器上,它知道如何通过网络与服务器联系。存根将远程方法所需的参数打包成一组字节。队参数编码的过程叫参数编组,参数编组的目的的将参数转换成适合在虚拟机之间进行传递的格式。在RMI协议中,对象是使用序列化机制来进行编码的,在SOAP协议中,对象被编码为XML。
    客户端的存根方法构造一个信息块,由以下部分组成:
        被使用的远程对象的标识符;
        被调用的方法的描述;
        编组后的参数。
    然后存根将此消息发送给服务器。服务器接收对象执行以下动作:
        定位要调用的远程对象;
        调用所需的方法,并传递客户端提供的参数;
        捕获返回值或该调用参生的异常;
        将返回值编组,打包返回给客户端存根。
    客户端存根对来自服务器端的返回值或异常进行反编组,就成为了调用存根的返回值。
   
RMI编程模型简单实例
    接口
  1. import java.rmi.Remote;
  2. import java.rmi.RemoteException;
  3.  
  4. /**
  5. * 简单仓库的远程借口
  6. * 远程对象的借口必须扩展Remote接口。接口中的所有方法必须声明抛出RemoteException异常,因为远程调用总是存在失败的可能。
  7. */
  8. public interface Warehouse extends Remote {
  9. double getPrice(String description) throws RemoteException;
  10. }

实现接口

  1. import java.rmi.RemoteException;
  2. import java.rmi.server.UnicastRemoteObject;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5.  
  6. /**
  7. * 实现简单仓库远程借口的类
  8. *该类是远程方法调用的目标。继承UnicastRemoteObject,这个类的构造器可以让它的对象供远程访问。
  9. *有时候不继承UnicastRemoteObject,在这种情况下需手动初始化远程对象,并将它们传给静态的exportObject方法。在远程对象的构造器中调用exportObject方法:UnicastRemoteObjcet.exportObject(this,0);
  10. */
  11. public class WarehouseImpl extends UnicastRemoteObject implements Warehouse {
  12. private Map<String,Double> prices;
  13.  
  14. public WarehouseImpl() throws RemoteException{
  15. prices = new HashMap<String,Double>();
  16. prices.put("Blackwell Toaster",24.95);
  17. prices.put("ZapXpress Microwave", 49.95);
  18. }
  19.  
  20. public double getPrice(String description) throws RemoteException {
  21. Double price = prices.get(description);
  22. return price == null ? 0 : price;
  23. }
  24.  
  25. }

构造并注册WarehouseImpl对象

  1. import java.rmi.RemoteException;
  2.  
  3. import javax.naming.Context;
  4. import javax.naming.InitialContext;
  5. import javax.naming.NamingException;
  6. /**
  7. * 第一个远程对象总要通过某种方式进行定位,JDK提供了自举注册服务。
  8. * 服务器程序使用自举注册服务来注册至少一个远程对象,要注册一个远程对象,需要一个RMI URL和一个对实现对象的引用。
  9. * RMI的URL以rmi:开头,后接服务器以及一个可选的端口号,接着是远程对象的名字。例如:rmi://regserver.mycompany.com:99/central_warehouse
  10. * 默认情况下,主机名是localhost,端口为1099。服务器告诉注册表在给定位置将该对象关联或“绑定”到这个名字。
  11. * 下面代码将一个WarehouseImpl对象注册到了同一个服务器上的RMI注册表中:
  12. WarehouseImpl centralWarehouse = new WarehouseImpl();
  13. Context namingContext = new InitialContext();
  14. namingContext.bind("rmi:central_warehouse", centralWarehouse);
  15. *
  16. */
  17. public class WarehouseServer {
  18. public static void main(String[] args) throws RemoteException,NamingException{
  19. System.out.println("Constructing server implementation...");
  20. WarehouseImpl centralWarehouse = new WarehouseImpl();
  21.  
  22. System.out.println("Binding server implementation to registry...");
  23. Context namingContext = new InitialContext();
  24. namingContext.bind("rmi:central_warehouse", centralWarehouse);
  25.  
  26. System.out.println("Waiting for invocations from clients...");
  27. }
  28. }

客户端获得远程对象

  1. import java.rmi.RemoteException;
  2. import java.util.Enumeration;
  3.  
  4. import javax.naming.Context;
  5. import javax.naming.InitialContext;
  6. import javax.naming.NameClassPair;
  7. import javax.naming.NamingException;
  8.  
  9. public class WarehouseClient {
  10. public static void main(String[] args) throws NamingException,RemoteException {
  11. Context namingContext = new InitialContext();
  12.  
  13. System.out.println("RMI registry bindings:");
  14. //通过下面的调用枚举所有注册过的RMI对象
  15. //NameClassPair是一个助手类,它包含绑定对象的名字和该对象所属类的名字
  16. Enumeration<NameClassPair> e = namingContext.list("rmi://localhost/");
  17. while(e.hasMoreElements()) {
  18. System.out.println(e.nextElement().getName());//打印注册对象的名字
  19. }
  20. //客户端通过下面方式来指定服务器和远程对象的名字,以此获得访问远程对象所需的存根
  21. String url = "rmi://localhost/central_warehouse";;
  22. Warehouse centralWarehouse = (Warehouse)namingContext.lookup(url);
  23.  
  24. String descr = "Blackwell Toaster";
  25. double price = centralWarehouse.getPrice(descr);
  26. System.out.println(descr+":"+price);
  27. }
  28. }

部署RMI简单实例

创建两个目录分别用于启动服务器和客户端的类
    server/
        WarehouseServer.class
        Warehouse.class
        WarehouseImpl.class
    client/
        WarehouseClient.class
        Warehouse.class
    部署RMI应用时,通常需要动态地将类交付为运行程序,其中一个例子就是RMI注册表。注册表的一个实例要服务许多不同的RMI应用。当注册表启动时,无法预测将来会参生的所有注册表请求。RMI注册表会动态地加载之前从未遇到过的所有远程接口的类文件。
    动态交付的类文件是通过标准的Web服务器发布的,服务器程序需使Warehouse.class文件对于RMI注册表来说是可获得的,所以将该文件放到第三个目录download中:
        download/
            Warehouse.class
    部署应用,服务器、RMI注册表、Web服务器和客户端可以定位到四台不同的机器上。(由于一台机器部署测试例子没看懂,所以具体一台机器测试没做笔记)
   

扩展

  1. javax.naming.InitialContext
  2. InitialContext() 构建一个命名上下文,用来访问RMI注册表。
  3. javax.naming.Context
  4. static Object lookup(String name) 返回给定名字的对象。如果该名字尚未绑定则抛出NamingException异常。
  5. static void bind(String name,Object obj) nameobj对象绑定。如果该对象已经绑定则抛出NameAlreadyBoundException异常。
  6. static void unbind(String name) 解除该名字的绑定。解除一个不存在的绑定是合法的。
  7. static void rebind(String name,Object obj) nameobj对象绑定。替换掉以前的绑定。
  8. NamingEnumeration<NameClassPair> list(String name) 返回一个枚举列表,列出所有匹配的绑定对象。使用“rmi:”调用该方法可以列出所有MRI对象。
  9. javax.naming.NameClassPair
  10. String getName() 获取已命名对象的名字。
  11. String getClassName() 获取已命名对象所属的类名。
  12. java.rmi.Naming
  13. static Remote lookup(String url) 返回URL对应的远程对象。如果该名字尚未绑定,抛NotBoundException异常。
  14. static void bind(String name,Remote obj) name和远程对象obj绑定。如果该对象已经绑定抛AlreadyBoundException异常。
  15. static void unbind(String name) 解除该名字的绑定。如果该名字没有绑定抛NotBound异常。
  16. static void rebind(String name,Remote obj) name和远程对象obj绑定。替换掉以前的绑定。
  17. static String[] list(String url) 参数url指定了某个注册表,返回注册表中的所有URL组成的字符串数组。

Java——分布式的更多相关文章

  1. Java分布式开发

    分布式概念的引入是基于性能的提升,应用的可靠性而提出的.所谓Java分布式,即是在使用Java语言进行企业级应用开发的过程中,采用分布式技术解决业务逻辑的高并发.高可用性的一些架构设计方案. 1. R ...

  2. 5个强大的Java分布式缓存框架推荐

    在开发中大型Java软件项目时,很多Java架构师都会遇到数据库读写瓶颈,如果你在系统架构时并没有将缓存策略考虑进去,或者并没有选择更优的 缓存策略,那么到时候重构起来将会是一个噩梦.本文主要是分享了 ...

  3. Java分布式处理技术(RMI,JDNI)

    http://hedaoyuan.blog.51cto.com/4639772/813702 1.1 RMI的基本概念 1.1.1 什么是RMI RMI(Remote Method Invocatio ...

  4. Java分布式缓存框架

    http://developer.51cto.com/art/201411/457423.htm 在开发中大型Java软件项目时,很多Java架构师都会遇到数据库读写瓶颈,如果你在系统架构时并没有将缓 ...

  5. Java分布式锁之数据库实现

    之前的文章<Java分布式锁实现>中列举了分布式锁的3种实现方式,分别是基于数据库实现,基于缓存实现和基于zookeeper实现.三种实现方式各有可取之处,本篇文章就详细讲解一下Java分 ...

  6. 学Java分布式和高架构,必懂的两大知识点!

    今天小编为你们分享阿里巴巴2018年招聘应届毕业生,Java工程师的面试考题,主要分为三种 Java中获取 mysql连接的方式: 第一部分:分布式   三步变成:分布式 1.将你的整个软件视为一个系 ...

  7. 深入浅出Java分布式系统通信

    对java分布式系统通信的理解: 1.集群模式,将相同应用模块部署多份 2.业务拆分模式,将业务拆分成多个模块,并分别部署 3.存储分布式 由于分布式概念太大,我们可以缩小下讨论的范围. 以下分布式的 ...

  8. JAVA分布式优惠券系统后台 手把手实战开发(买的,完整)

    扫码关注,回复 “java分布式优惠券”,免费领取.本资源是本人花几十块买的,完整.

  9. java 分布式与集群的区别和联系(转)

    本文主要介绍了java分布式与集群的区别和联系,具有很好的参考价值,下面跟着小编一起来看下吧 一.先说区别: 一句话:分布式是并联工作的,集群是串联工作的. 1.分布式是指将不同的业务分布在不同的地方 ...

  10. 5个强大的Java分布式缓存框架

    在开发中大型Java软件项目时,很多Java架构师都会遇到数据库读写瓶颈,如果你在系统架构时并没有将缓存策略考虑进去,或者并没有选择更优的缓存策略,那么到时候重构起来将会是一个噩梦.本文主要是分享了5 ...

随机推荐

  1. 解析HTML、JS与PHP之间的数据传输

    在电商网站搭建过程中,前端经常会向后端请求数据,有时候通过HTML.JS和PHP文件的处理来实现数据的连通.通常情况下,用户在HTML中做关键字操作,JS对提交的表单进行数据处理,向后端发起ajax请 ...

  2. Radware:上周五美国大规模DDoS攻击是如何发生的

    10月21日上午,Dyn遭受到拒绝服务(DoS)攻击,造成了托管DNS网络的中断.成千上万的网站因此变得不可访问,其中包括Amazon EC2.当天晚些时候,当攻击者发起第二轮针对Dyn DNS系统的 ...

  3. ubuntu 和 centos 如何区分系统

    Ubuntu Ubuntu有着漂亮的用户界面,完善的包管理系统,强大的软件源支持,丰富的技术社区,Ubuntu还对大多数硬件有着良好的兼容性,包括最新的图形显卡等等.这一切让Ubuntu越来越向大众化 ...

  4. xml出现Exception in thread "main" java.lang.NullPointerException

    运行代码出现Exception in thread "main" java.lang.NullPointerException 可以看下这个链接:https://ask.csdn. ...

  5. ArcMap 0 (ArcGIS10.2安装)

    一如GIS深似海,从此相逢是故人(这句话适合初步接触GIS的,我算是初窥门径.还是道行太浅,只是多了感慨) 前言: 1. 本人GIS专业,对于ArcGIS较为熟悉.由于专业和其它经历需要,接触过不少各 ...

  6. 【XR-3】核心城市(树直径)

    [XR-3]核心城市 这题真的难啊......... k个核心城市太麻烦,我们假设先找一个核心城市,应该放在哪里? \(任意取一个点,它的最远端是直径的端点.\) \(所以当这个点是直径的中点时,可以 ...

  7. crontab自动启动小任务例子(每一分钟将当前日期打入一个文件)

      crontab -l #查看当前定时任务列表 显示没有,那么我们来安装一下(必须在root用户下) – yum install vixie-cron  – yum install crontabs ...

  8. opencv-12-高斯滤波-双边滤波(附C++代码实现)

    开始之前 这几天由于自己的原因没有写, 一个是因为自己懒了, 一个是感觉这里遇到点问题不想往下写了, 我们先努力结束这个章节吧, 之前介绍了比较常用而且比较好理解的均值和中值滤波, 但是呢,在例程Sm ...

  9. 基于Kubernetes服务发现机制的探讨Non Service

    服务注册 注册中⼼作为一般的RPC/Web服务中的底层设施提供了服务进程元数据(IP, Port, Interface, Group,Method等)存储,被Watch的功能,每个服务进程均需接⼊同⼀ ...

  10. 经典sql语句大全,【转载】

    经典SQL查询语句大全   一.基础1.说明:创建数据库CREATE DATABASE database-name2.说明:删除数据库drop database dbname3.说明:备份sql se ...