java远路通讯可选技术

java远程通讯可选技术
在分布式服务框架中,一个最基础的问题就是远程服务是怎么通讯的,在Java领域中有很多可实现远程通讯的技术,例如:RMI、MINA、ESB、 Burlap、Hessian、SOAP、EJB和JMS等,这些名词之间到底是些什么关系呢,它们背后到底是基于什么原理实现的呢,了解这些是实现分布式服务框架的基础知识,而如果在性能上有高的要求的话,那深入了解这些技术背后的机制就是必须的了,在这篇blog中我们将来一探究竟,抛砖引玉,欢迎大家提供更多的实现远程通讯的技术和原理的介绍。

基本原理
要实现网络机器间的通讯,首先得来看看计算机系统网络通信的基本原理,在底层层面去看,网络通信需要做的就是将流从一台计算机传输到另外一台计算机,基于传输协议和网络IO来实现,其中传输协议比较出名的有http、tcp、udp等等,http、tcp、udp都是在基于Socket概念上为某类应用场景而扩展出的传输协议,网络IO,主要有bio、nio、aio三种方式,所有的分布式应用通讯都基于这个原理而实现,只是为了应用的易用,各种语言通常都会提供一些更为贴近应用易用的应用层协议。

应用级协议
远程服务通讯,需要达到的目标是在一台计算机发起请求,另外一台机器在接收到请求后进行相应的处理并将结果返回给请求端,这其中又会有诸如one way request、同步请求、异步请求等等请求方式,按照网络通信原理,需要实现这个需要做的就是将请求转换成流,通过传输协议传输至远端,远端计算机在接收到请求的流后进行处理,处理完毕后将结果转化为流,并通过传输协议返回给调用端。
原理是这样的,但为了应用的方便,业界推出了很多基于此原理之上的应用级的协议,使得大家可以不用去直接操作这么底层的东西,通常应用级的远程通信协议会提供:
1、为了避免直接做流操作这么麻烦,提供一种更加易用或贴合语言的标准传输格式;
2、网络通信机制的实现,就是替你完成了将传输格式转化为流,通过某种传输协议传输至远端计算机,远端计算机在接收到流后转化为传输格式,并进行存储或以某种方式通知远端计算机。
所以在学习应用级的远程通信协议时,我们可以带着这几个问题进行学习:
1、传输的标准格式是什么?
2、怎么样将请求转化为传输的流?
3、怎么接收和处理流?
4、传输协议是?
不过应用级的远程通信协议并不会在传输协议上做什么多大的改进,主要是在流操作方面,让应用层生成流和处理流的这个过程更加的贴合所使用的语言或标准,至于传输协议则通常都是可选的,在java领域中知名的有:RMI、XML-RPC、Binary-RPC、SOAP、CORBA、JMS,来具体的看看这些远程通信的应用级协议:
--------------------------------------------------------------------------
RMI
RMI是java的椅子用户开发分布式应用程序的API,也是个典型的为java定制的远程通信协议,RMI使用java语言定义了远程对象,它集合了java序列化和java远程方法协议,以前的程序是在用一操作系统的方法调用,变成了不同操作系统之间程序的方法调用,我们都知道,在single vm中,我们可以通过直接调用java object instance来实现通信,那么在远程通信时,如果也能按照这种方式当然是最好了,这种远程通信的机制成为RPC(Remote Procedure Call),RMI正是朝着这个目标而诞生的。

RMI远程方法调用:
是java的网络分布式应用系统的能力上,支持与不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的无缝远程调用。

RMI的目的:
给应用程序开发者提供一个调用远程对象方法的抽象功能,而不必采用低级通信。java rmi开发的应用系统可以部署在任何支持jre的平台上。

运行机制:
服务器程序和客户端程序。
服务器程序将创建多个远程对象,使这些远程对象能够被引用,然后等待客户端调用这些远程对象内部的方法,客户端程序则从服务器中得到一个或多个远程对象的引用,然后调用远程对象的方法。RMI为服务器和客户端通信传递提供一种方便的机制。
RMI通过stub(存根)和skeleton(骨架)机制来实现客户端与远程服务的交互。
RMI包括三层:存根/骨架层(stubs/skeletons)、远程引用层(remote reference layer)和传输层(transport)
客户机在调用远程方法时,请求功能在客户机。

来看下基于RMI的一次完整的远程通信过程的原理:
1、客户端发起请求,请求转交至RMI客户端的stub类;
2、stub类将请求的接口、方法、参数等信息进行序列化;
3、基于socket将序列化后的流传输至服务器端;
4、服务器端接收到流后转发至相应的skelton类;
5、skelton类将请求的信息反序列化后调用实际的处理类;
6、处理类处理完毕后将结果返回给skelton类;
7、Skelton类将结果序列化,通过socket将流传送给客户端的stub;
8、stub在接收到流后反序列化,将反序列化后的Java Object返回给调用者。
来看jboss-remoting对于此过程的一个更好的图示:

根据原理来回答下之前学习应用级协议带着的几个问题:
1、传输的标准格式是什么?
是Java ObjectStream。
2、怎么样将请求转化为传输的流?
基于Java串行化机制将请求的java object信息转化为流。
3、怎么接收和处理流?
根据采用的协议启动相应的监听端口,当有流进入后基于Java串行化机制将流进行反序列化,并根据RMI协议获取到相应的处理对象信息,进行调用并处理,处理完毕后的结果同样基于java串行化机制进行返回。
4、传输协议是?
Socket。

XML-RPC
XML-RPC也是一种和RMI类似的远程调用的协议,它和RMI的不同之处在于它以标准的xml格式来定义请求的信息(请求的对象、方法、参数等),这样的好处是什么呢,就是在跨语言通讯的时候也可以使用。
来看下XML-RPC协议的一次远程通信过程:
1、客户端发起请求,按照XML-RPC协议将请求信息进行填充;
2、填充完毕后将xml转化为流,通过传输协议进行传输;
3、接收到在接收到流后转换为xml,按照XML-RPC协议获取请求的信息并进行处理;
4、处理完毕后将结果按照XML-RPC协议写入xml中并返回。

同样来回答问题:
1、传输的标准格式是?
标准格式的XML。
2、怎么样将请求转化为传输的流?
将XML转化为流。
3、怎么接收和处理流?
通过监听的端口获取到请求的流,转化为XML,并根据协议获取请求的信息,进行处理并将结果写入XML中返回。
4、传输协议是?
Http。

Binary-RPC
Binary-RPC看名字就知道和XML-RPC是差不多的了,不同之处仅在于传输的标准格式由XML转为了二进制的格式。
同样来回答问题:
1、传输的标准格式是?
标准格式的二进制文件。
2、怎么样将请求转化为传输的流?
将二进制格式文件转化为流。
3、怎么接收和处理流?
通过监听的端口获取到请求的流,转化为二进制文件,根据协议获取请求的信息,进行处理并将结果写入XML中返回。
4、传输协议是?
Http。

--------------------------------------------------------------------------

CORBA
Common Object Request Broker Architecture (公用对象请求代理[调度]程序体系结构),是一组用来定义“分布式对象系统”的标准,由OMG(Object Menagement Group)作为发起和标准制定单位。CORBA的目的是定义一套协议,符合这个协议的对象可以互相交互,不论它们是用什么样的语言写的,不论它们运行于什么样的机器和操作系统。
CORBA在我看来是个类似于SOA的体系架构,涵盖可选的远程通信协议,但其本身不能列入通信协议这里来讲,而且CORBA基本淘汰,再加上对CORBA也不怎么懂,在此就不进行阐述了。

--------------------------------------------------------------------------

JMS
JMS呢,是实现java领域远程通信的一种手段和方法,基于JMS实现远程通信时和RPC是不同的,虽然可以做到RPC的效果,但因为不是从协议级别定义的,因此我们不认为JMS是个RPC协议,但它确实是个远程通信协议,在其他的语言体系中也存在着类似JMS的东西,可以统一的将这类机制称为消息机制,而消息机制呢,通常是高并发、分布式领域推荐的一种通信机制,这里的主要一个问题是容错(详细见ErLang论文)。
来看JMS中的一次远程通信的过程:
1、客户端将请求转化为符合JMS规定的Message;
2、通过JMS API将Message放入JMS Queue或Topic中;
3、如为JMS Queue,则发送中相应的目标Queue中,如为Topic,则发送给订阅了此Topic的JMS Queue。
4、处理端则通过轮训JMS Queue,来获取消息,接收到消息后根据JMS协议来解析Message并处理。
回答问题:
1、传输的标准格式是?
JMS规定的Message。
2、怎么样将请求转化为传输的流?
将参数信息放入Message中即可。
3、怎么接收和处理流?
轮训JMS Queue来接收Message,接收到后进行处理,处理完毕后仍然是以Message的方式放入Queue中发送或Multicast。
4、传输协议是?
不限。
基于JMS也是常用的实现远程异步调用的方法之一。

--------------------------------------------------------------------------
1.MINA框架介绍:
    当客户首次访问采用MINA编写的程序时,ioacceptor作为线程运行,负责接受来自客户的请求。当有客户请求连接时,创建一个session,该session与ioprocessor、socletChannel以及ioservice联系起来。ioprocessor也作为另一个线程运行,定时检查客户是否有数据到来,并对客户请求进行处理,依次调用在ioservice注册的各个iofilter,最后调用iohandler进行最终的逻辑处理,再将处理后的结果filter后返回给客户端。
2.iosession
session可以理解魏服务器与客户端的特定连接,该连接由服务器地址、端口以及客户端地址、端口来决定。客户端发起请求时,制定服务器地址和端口,客户端也会制定或者根据网络路由信息自动制定一个地址、自动分配一个端口。这个地址、端口构成一个session。
session是服务器端对这种连接的抽象,MINA对其进行了封装,定义了iosession接口,用来代表客户端服务器的连接,在服务器端来指代客户端,实现对客户端的操作、绑定与客户端有关的信息与对象。通过利用session的这个概念,编写程序时就可以在服务器端非常方便地区分出当前处理的是那个客户端的请求、维持客户端的状态信息、可以实现客户端之间相互通讯。
iosession提供一些常用方法:
(1)setAttribute(object key,object value);getAttribute(Object key);    设置/获取用户定义的属性。
将该属性与session联系起来,方便以后处理用户请求时使用。比如,如果要求用户登录后才能继续进行操作,那么在用户成功登录后,可以通过setAttribute()设置一个属性,当用户以后继续请求时,可以通过getAttribute()来获取该属性来判断用户时候登录。
(2)getRemoteAddress()   获取远程客户端地址。
(3)getid()   getCreationTime()   getLastIoTime()   getConfig()
获取session的id、创建时间、上次IO时间、配置信息。
(4)write(Object message)   将数据发送给客户端。
(5)close()   关闭session
说明:可以在session中发送数据,但是session没有提供读取数据的方法,读取数据通过另一套机制在ioHandle的messageReceived()中实现。
3.Event
MINA可以看成是时间驱动的。通常在网络通讯中,可以将整个过程划分为几个基本的阶段,如建立连接、数据通信、关闭连接。
数据通信一般包括数据的发送和接受,由于在通信过程中,可能要多次发送和接受数据,以进行不同的业务交互。
不可能一直都接受和发送数据,因此就有idle出现,在MINA中,如果在设定的时间内没有数据发送或接受,那么就会出发一个idle事件。
由于某种原因,可能会发生错误,导致系统异常发生,引发exception.
因此,如果从时间发生的角度看的话,就可以在MINA中将通信看成由一个建立连接(sessionCreated和sessionOpened)、多个数据接受和发送、一个关闭连接事件以及多个idle事件等7种时间组成的过程。
session是对方互相通信的抽象,因此通信的过程就是一系列与session相关的事件。
在MINA现在对TCP的实现中,sessionCreated和sessionOpened没有区别。因此严格来说,有6种类型的事件。
4.ioHandler
从以上MINA框架可以看出,对来自客户端数据最终处理是在iohandler中处理的。iohandler封装了来自客户端不同事件的处理,如果对某个事件感兴趣,可以实现相应的方法,当该事件发生时,iohandler中的方法就会被出发执行。

--------------------------------------------------------------------------

ESB(实现SOA的基础架构)
1.何为ESB:全程Enterprise Service Bus,即企业服务总线。它是传统中间件技术与XML、web 服务等技术结合的产物。ESB提供了网络中最基本的连接中枢,是构筑企业神经系统的必要元素。(ESB是集成技术和SOA思想结合的产物)
2.基本功能:
服务的MetaDate管理:在总线范畴内对服务的注册命名及寻址功能。
传输服务:必须确保通过企业总线互联的业务流程间的消息的正确交付,传输还包括基于内容的路由功能。
中介:提供位置透明性的服务路由和定位服务;多种消息传递形式;支持广泛使用的传输协议。
多种服务集成方式:如JCA、WEB服务、Messaging、Adaptor等。
服务和事件管理支持:如服务的调用记录、测量和监控数据;提供事件检测、触发和发布功能。
面向服务的元数据管理:他必须了解被他中介的两端,即服务的请求以及请求者对服务的要求,以及服务的提供者和他所提供的描述;
Mediation:他必须具有某种机制能够完成中介的作用,如协议转换;
通信:服务发布、订阅,相应请求,同步异步消息,路由和寻址等;
集成:一流系统适配器,服务编排和映射,协议转化,数据变换,企业应用集成中间件的连续等。
3.ESB的用途
ESB只是一个基于消息的调用企业服务的通信模块!可以将他嵌入到应用程序框架中,列入嵌入到spring容器里面,或者嵌入到工作流系统中。他的作用是对企业里面的SOA(面向服务体系架构)服务的调用提供一个框架和简便的方法。
4.ESB的应用特征
ESB是传统中间件技术与XML、web 服务等技术相互结合的产物,用于实现企业应用不同消息和信息的准确、高效和安全传递。
可以实现不同服务之间的通信与整合。ESB在不同领域具有非常广泛的用途。
5.ESB的意义
ESB提供了时间驱动和文档导向的处理模式,以及分布式的运行管理机制,它支持基于内容的路由和过滤,具备了复杂数据的传输能力,并可以提供一系列的标准接口。
6. ESB是逻辑上与SOA所遵循的基本原则保持一致的服务集成基础架构,它提供了服务管理的方法和在分布式异构环境中进行服务交互的功能。

--------------------------------------------------------------------------

Burlap   (http://qq85609655.iteye.com/blog/970266)

burlap也是caucho提供,它和hessian的不同在于,它是基于AML-RPC协议的。
发起请求是由Burlap提供的API发起的。
转化符合协议的格式是将请求信息转化为符合协议的XML格式,再转化为流进行传输。
使用HTTP进行传输。
相应端基于监听HTTP请求机制来接受请求。
根据XML-RPC协议进行还原将流还原为传输格式。
处理完毕后,返回结果写入XML中,由Burlap返回至调用端。

--------------------------------------------------------------------------

hessian  (http://baike.baidu.com/view/2255290.htm#1)
是一个轻量级的remoting onhttp工具,使用简单的方法提供了RMI的功能,相比webservice,hessian更简单、快捷。采用的是二进制RPC协议(binary-rpc),因为采用的是二进制协议,所以它很适合于发送二进制数据。
注意点:hessian设计接口,给客户端调用,配置web.xml时要配置相应的servlet,并且必须实现seriazable接口,复杂对象使用map方法传递。
远程调用接口使用hessianProxyFactory.

--------------------------------------------------------------------------

SOAP  (http://baike.baidu.com/view/60663.htm)
SOAP原意为Simple Object Access Protocol,是一个用于分布式环境的、轻量级的、基于XML进行信息交换的通信协议,可以认为SOAP是XML RPC的高级版,两者的原理完全相同,都是http+XML,不同的仅在于两者定义的XML规范不同,SOAP也是Webservice采用的服务调用协议标准,因此在此就不多加阐述了。
用途:可以和现存的许多英特网协议和格式协议结合使用,包括超文本传输协议(http),简单邮件传输协议(smtp),多用途邮件扩充协议(mime)。它还支持从消息系统到远程过程调用(rpc)等大量的应用程序。
优势:
1.具有可扩展性,SOAP客户端、服务器和协议自身都能发展。而且SOAP能极好地支持中间介质和层次化的体系结构。
2.简单,使用XML格式发送请求,调用对应的对象,然后服务器返回结果。
3.SOAP可以相对于平台、操作系统、目标模型和编程语言独立实现。传输和语言绑定以及数据编码的参数选择都是由具体的实现决定的。
4.SOAP可以使用任何语言来完成,只要客户端发送正确SOAP请求(传递适合的参数给一个远端服务器)。SOAP没有对象模型,应用程序可以绑定在任何对象模型中。
5.SOAP在任何操作系统中无需改动正常运行。
劣:soapfault生成soap访问出错,创建soapfault

--------------------------------------------------------------------------

EJB
EJB是服务器端的组建模型,设计与核心应用是部署分布式应用程序。不限平台,用于开发基于组建的企业应用程序的标准。特点包括网络服务支持和核心开发工具(SDK)。
以注释为基础的编程模型,注释可以用于定义bean业务接口、O/R映射信息、资源引用信息;
优:开发人员只需要关注业务逻辑的实现,而不用关心底层的实现机制。支持多个事务处理,同时成功或者同时失败;可以用代码来定义事务级别可扩展性;提供负载均衡和安全性;

新的持久化模型
被加了注释的简单的java对象pojo。一旦它被EntityManager访问它就成为了一个持久化对象,并且成为了持久化上下文的一部分。持久化的上下文与事务上下文是松耦合的(松耦合系统的优点在于更新一个模块不会引起其它模块的改变);实体关系映射通过注释定义,O/R映射也是,并有多种数据库规范操作。

无状态会话bean
在EJB规范中,写无状态会话bean只需要一个简单的java文件并在类层加上@Stateless注释就可以了。

有状态会话bean
这些初始化操作可以通过自定义方法完成,并把他们暴露在接口中。在使用bean之前由客户端来调用相应的初始化方法。
bean的提供者可以用@Remove注释来标记任何SFSB的方法,以说明被调用之后bean的实例将被移除。

消息驱动bean
消息驱动不饿安是唯一一种必须实现一个业务接口的bean。这个接口指出bean支持的是哪一种消息系统。

实体bean
实体bean使用@Entity注释来标记,所有实体bean中的属性/字段不必使用@Transient注释来标记。实体bena的持久化字段可以通过javabean-style机制或者声明为public/protacted字段来实现。

实体关联
支持bean之间双向的合单向的关联,可以是一对一等等关联,双向关联的两端还要分为自身端和对方端。自身端向数据库通告关联的变更。

O/R映射模型将通过bean类中的注释来声明。而且此方法还会指出对应的具体表和字段。O/R映射模型提供了一套自有的SQL;而且除了提供一些基本的SQL外还支持某些高层开发的功能。

客户端程序模型
一个EJB客户端可以通过@Inject注释以一种“注入”的方式获得一个bean的业务接口应用。也可以使用另一个注释@javax.ejb.EJBContext.lookup()来完成上面的操作。

EJB QL
EJB QL 可以通过@NamedQuery来注释。这个注释有两个成员属性分别是name和queryString.一旦定义了这些属性,就可以通过EntityManager.createNamedQuery(name)来指向这个查询。也可以创建一个标准的JDBC风格的查询并使用 EntiityManager.createQuery(ejbqlString)或EntityManager.createNativeQuery(natitySqlString)(这个方法用于执行一个本地查询)来执行查询。

解决同一个容器的兼容问题:先利用EJB文件生成类似于EJB2.1部署模式的文件(包括必要的接口和部署描述符)然后再用类似于EJB2.1的方式来部署这个EJB组建。

--------------------------------------------------------------------------