Java——分布式
客户端和服务端之间用代理进行通讯,客户端调用代理进行常规的方法调用,而客户端代理与服务端代理进行联系,服务端代理以常规方式调用服务器对象上的方法。
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。
客户端的存根方法构造一个信息块,由以下部分组成:
被使用的远程对象的标识符;
被调用的方法的描述;
编组后的参数。
然后存根将此消息发送给服务器。服务器接收对象执行以下动作:
定位要调用的远程对象;
调用所需的方法,并传递客户端提供的参数;
捕获返回值或该调用参生的异常;
将返回值编组,打包返回给客户端存根。
客户端存根对来自服务器端的返回值或异常进行反编组,就成为了调用存根的返回值。
- import java.rmi.Remote;
- import java.rmi.RemoteException;
- /**
- * 简单仓库的远程借口
- * 远程对象的借口必须扩展Remote接口。接口中的所有方法必须声明抛出RemoteException异常,因为远程调用总是存在失败的可能。
- */
- public interface Warehouse extends Remote {
- double getPrice(String description) throws RemoteException;
- }
实现接口
- import java.rmi.RemoteException;
- import java.rmi.server.UnicastRemoteObject;
- import java.util.HashMap;
- import java.util.Map;
- /**
- * 实现简单仓库远程借口的类
- *该类是远程方法调用的目标。继承UnicastRemoteObject,这个类的构造器可以让它的对象供远程访问。
- *有时候不继承UnicastRemoteObject,在这种情况下需手动初始化远程对象,并将它们传给静态的exportObject方法。在远程对象的构造器中调用exportObject方法:UnicastRemoteObjcet.exportObject(this,0);
- */
- public class WarehouseImpl extends UnicastRemoteObject implements Warehouse {
- private Map<String,Double> prices;
- public WarehouseImpl() throws RemoteException{
- prices = new HashMap<String,Double>();
- prices.put("Blackwell Toaster",24.95);
- prices.put("ZapXpress Microwave", 49.95);
- }
- public double getPrice(String description) throws RemoteException {
- Double price = prices.get(description);
- return price == null ? 0 : price;
- }
- }
构造并注册WarehouseImpl对象
- import java.rmi.RemoteException;
- import javax.naming.Context;
- import javax.naming.InitialContext;
- import javax.naming.NamingException;
- /**
- * 第一个远程对象总要通过某种方式进行定位,JDK提供了自举注册服务。
- * 服务器程序使用自举注册服务来注册至少一个远程对象,要注册一个远程对象,需要一个RMI URL和一个对实现对象的引用。
- * RMI的URL以rmi:开头,后接服务器以及一个可选的端口号,接着是远程对象的名字。例如:rmi://regserver.mycompany.com:99/central_warehouse
- * 默认情况下,主机名是localhost,端口为1099。服务器告诉注册表在给定位置将该对象关联或“绑定”到这个名字。
- * 下面代码将一个WarehouseImpl对象注册到了同一个服务器上的RMI注册表中:
- WarehouseImpl centralWarehouse = new WarehouseImpl();
- Context namingContext = new InitialContext();
- namingContext.bind("rmi:central_warehouse", centralWarehouse);
- *
- */
- public class WarehouseServer {
- public static void main(String[] args) throws RemoteException,NamingException{
- System.out.println("Constructing server implementation...");
- WarehouseImpl centralWarehouse = new WarehouseImpl();
- System.out.println("Binding server implementation to registry...");
- Context namingContext = new InitialContext();
- namingContext.bind("rmi:central_warehouse", centralWarehouse);
- System.out.println("Waiting for invocations from clients...");
- }
- }
客户端获得远程对象
- import java.rmi.RemoteException;
- import java.util.Enumeration;
- import javax.naming.Context;
- import javax.naming.InitialContext;
- import javax.naming.NameClassPair;
- import javax.naming.NamingException;
- public class WarehouseClient {
- public static void main(String[] args) throws NamingException,RemoteException {
- Context namingContext = new InitialContext();
- System.out.println("RMI registry bindings:");
- //通过下面的调用枚举所有注册过的RMI对象
- //NameClassPair是一个助手类,它包含绑定对象的名字和该对象所属类的名字
- Enumeration<NameClassPair> e = namingContext.list("rmi://localhost/");
- while(e.hasMoreElements()) {
- System.out.println(e.nextElement().getName());//打印注册对象的名字
- }
- //客户端通过下面方式来指定服务器和远程对象的名字,以此获得访问远程对象所需的存根
- String url = "rmi://localhost/central_warehouse";;
- Warehouse centralWarehouse = (Warehouse)namingContext.lookup(url);
- String descr = "Blackwell Toaster";
- double price = centralWarehouse.getPrice(descr);
- System.out.println(descr+":"+price);
- }
- }
部署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服务器和客户端可以定位到四台不同的机器上。(由于一台机器部署测试例子没看懂,所以具体一台机器测试没做笔记)
扩展
- javax.naming.InitialContext
- InitialContext() 构建一个命名上下文,用来访问RMI注册表。
- javax.naming.Context
- static Object lookup(String name) 返回给定名字的对象。如果该名字尚未绑定则抛出NamingException异常。
- static void bind(String name,Object obj) 将name和obj对象绑定。如果该对象已经绑定则抛出NameAlreadyBoundException异常。
- static void unbind(String name) 解除该名字的绑定。解除一个不存在的绑定是合法的。
- static void rebind(String name,Object obj) 将name和obj对象绑定。替换掉以前的绑定。
- NamingEnumeration<NameClassPair> list(String name) 返回一个枚举列表,列出所有匹配的绑定对象。使用“rmi:”调用该方法可以列出所有MRI对象。
- javax.naming.NameClassPair
- String getName() 获取已命名对象的名字。
- String getClassName() 获取已命名对象所属的类名。
- java.rmi.Naming
- static Remote lookup(String url) 返回URL对应的远程对象。如果该名字尚未绑定,抛NotBoundException异常。
- static void bind(String name,Remote obj) 将name和远程对象obj绑定。如果该对象已经绑定抛AlreadyBoundException异常。
- static void unbind(String name) 解除该名字的绑定。如果该名字没有绑定抛NotBound异常。
- static void rebind(String name,Remote obj) 将name和远程对象obj绑定。替换掉以前的绑定。
- static String[] list(String url) 参数url指定了某个注册表,返回注册表中的所有URL组成的字符串数组。
Java——分布式的更多相关文章
- Java分布式开发
分布式概念的引入是基于性能的提升,应用的可靠性而提出的.所谓Java分布式,即是在使用Java语言进行企业级应用开发的过程中,采用分布式技术解决业务逻辑的高并发.高可用性的一些架构设计方案. 1. R ...
- 5个强大的Java分布式缓存框架推荐
在开发中大型Java软件项目时,很多Java架构师都会遇到数据库读写瓶颈,如果你在系统架构时并没有将缓存策略考虑进去,或者并没有选择更优的 缓存策略,那么到时候重构起来将会是一个噩梦.本文主要是分享了 ...
- Java分布式处理技术(RMI,JDNI)
http://hedaoyuan.blog.51cto.com/4639772/813702 1.1 RMI的基本概念 1.1.1 什么是RMI RMI(Remote Method Invocatio ...
- Java分布式缓存框架
http://developer.51cto.com/art/201411/457423.htm 在开发中大型Java软件项目时,很多Java架构师都会遇到数据库读写瓶颈,如果你在系统架构时并没有将缓 ...
- Java分布式锁之数据库实现
之前的文章<Java分布式锁实现>中列举了分布式锁的3种实现方式,分别是基于数据库实现,基于缓存实现和基于zookeeper实现.三种实现方式各有可取之处,本篇文章就详细讲解一下Java分 ...
- 学Java分布式和高架构,必懂的两大知识点!
今天小编为你们分享阿里巴巴2018年招聘应届毕业生,Java工程师的面试考题,主要分为三种 Java中获取 mysql连接的方式: 第一部分:分布式 三步变成:分布式 1.将你的整个软件视为一个系 ...
- 深入浅出Java分布式系统通信
对java分布式系统通信的理解: 1.集群模式,将相同应用模块部署多份 2.业务拆分模式,将业务拆分成多个模块,并分别部署 3.存储分布式 由于分布式概念太大,我们可以缩小下讨论的范围. 以下分布式的 ...
- JAVA分布式优惠券系统后台 手把手实战开发(买的,完整)
扫码关注,回复 “java分布式优惠券”,免费领取.本资源是本人花几十块买的,完整.
- java 分布式与集群的区别和联系(转)
本文主要介绍了java分布式与集群的区别和联系,具有很好的参考价值,下面跟着小编一起来看下吧 一.先说区别: 一句话:分布式是并联工作的,集群是串联工作的. 1.分布式是指将不同的业务分布在不同的地方 ...
- 5个强大的Java分布式缓存框架
在开发中大型Java软件项目时,很多Java架构师都会遇到数据库读写瓶颈,如果你在系统架构时并没有将缓存策略考虑进去,或者并没有选择更优的缓存策略,那么到时候重构起来将会是一个噩梦.本文主要是分享了5 ...
随机推荐
- 解析HTML、JS与PHP之间的数据传输
在电商网站搭建过程中,前端经常会向后端请求数据,有时候通过HTML.JS和PHP文件的处理来实现数据的连通.通常情况下,用户在HTML中做关键字操作,JS对提交的表单进行数据处理,向后端发起ajax请 ...
- Radware:上周五美国大规模DDoS攻击是如何发生的
10月21日上午,Dyn遭受到拒绝服务(DoS)攻击,造成了托管DNS网络的中断.成千上万的网站因此变得不可访问,其中包括Amazon EC2.当天晚些时候,当攻击者发起第二轮针对Dyn DNS系统的 ...
- ubuntu 和 centos 如何区分系统
Ubuntu Ubuntu有着漂亮的用户界面,完善的包管理系统,强大的软件源支持,丰富的技术社区,Ubuntu还对大多数硬件有着良好的兼容性,包括最新的图形显卡等等.这一切让Ubuntu越来越向大众化 ...
- xml出现Exception in thread "main" java.lang.NullPointerException
运行代码出现Exception in thread "main" java.lang.NullPointerException 可以看下这个链接:https://ask.csdn. ...
- ArcMap 0 (ArcGIS10.2安装)
一如GIS深似海,从此相逢是故人(这句话适合初步接触GIS的,我算是初窥门径.还是道行太浅,只是多了感慨) 前言: 1. 本人GIS专业,对于ArcGIS较为熟悉.由于专业和其它经历需要,接触过不少各 ...
- 【XR-3】核心城市(树直径)
[XR-3]核心城市 这题真的难啊......... k个核心城市太麻烦,我们假设先找一个核心城市,应该放在哪里? \(任意取一个点,它的最远端是直径的端点.\) \(所以当这个点是直径的中点时,可以 ...
- crontab自动启动小任务例子(每一分钟将当前日期打入一个文件)
crontab -l #查看当前定时任务列表 显示没有,那么我们来安装一下(必须在root用户下) – yum install vixie-cron – yum install crontabs ...
- opencv-12-高斯滤波-双边滤波(附C++代码实现)
开始之前 这几天由于自己的原因没有写, 一个是因为自己懒了, 一个是感觉这里遇到点问题不想往下写了, 我们先努力结束这个章节吧, 之前介绍了比较常用而且比较好理解的均值和中值滤波, 但是呢,在例程Sm ...
- 基于Kubernetes服务发现机制的探讨Non Service
服务注册 注册中⼼作为一般的RPC/Web服务中的底层设施提供了服务进程元数据(IP, Port, Interface, Group,Method等)存储,被Watch的功能,每个服务进程均需接⼊同⼀ ...
- 经典sql语句大全,【转载】
经典SQL查询语句大全 一.基础1.说明:创建数据库CREATE DATABASE database-name2.说明:删除数据库drop database dbname3.说明:备份sql se ...