分布式服务框架
一、 引言:
分布式服务在企业应用之重,不再多说。本文主要介绍分布式服务框架涉及的基本网络通信原理、应用级远程通信协议介绍和流行的分布式服务框架介绍,以达到对分布式服务框架的整体理解。
二、 网络通信的基本原理:
从层面意思理解,网络通信需要将数据从一台机器传输到另一台机器,达到多台机器通信目的,具体的网络传输方式基于传输协议和网络IO。其中比较常见的传输协议有:HTTP、TCP、UDP等,HTTP、TCP、UDP协议也是基于SOCKET概念上为某类应用场景而拓展出来的传输协议。网络IO主要有BIO、NIO、AIO三种方式。所有的分布式通信协议都应该基于这个原理而实现。
三、 应用级远程通信协议:
在网络通信传输的基本原理中,需要将传输数据转化成流,通过某种协议传输到另一台计算机,远程计算机接收到流后,需要反转化成正确数据,在对数据进行处理后,通过相同的方式响应调用端计算机。
那么分布式服务框架的出现就是封装繁杂的流转换,替换成一种更加易用和理解的新的标准传输协议。但在学习分布式服务框架时,同样需要按照如下问题进行思考:
1. 数据传输的标准格式
2. 基本的数据传输协议
3. 数据与流之间的转化方式
4. 接受和处理流的方式
如下,对分布式服务框架使用的新标准协议进行讨论。
1. RMI
Java 远程方法调用(Java Remote Method Invocation),一种用于实现远程过程调用的应用程序编程接口。它使客户机上运行的程序可以调用远程服务器上的对象。
下面来看基于RMI的远程通信过程和原理。
1.1 客户端发起请求,请求转交至RMI客户端的Stub类;
1.2 Stub类将请求的接口、方法、参数等信息进行序列化;
1.3 基于socket将序列化的对象流传输到服务端;
1.4 服务端将接受到的序列化流转化至相应的skelton类;
1.5 Skelton类将请求的信息反序列化后调用实际的处理类;
1.6 处理类处理完毕后将结果返回给skelton类;
1.7 Skelton将结果序列化,通过socket将流传输给客户端stub类;
1.8 Stub类将结果反序列化的对象返回给调用者。
下面是jboss-remoting对于此过程的示图。
思考问题:
1.1 数据传输的标准格式
Java ObjectStream,故请求参数需要进行序列化。
1.2 基本的数据传输协议
Socket
1.3 数据与流之间的转化方式
基于java的串行化机制将请求和响应对象转化为流。
1.4 接受和处理流的方式
程序监听响应的端口号,但有流进入后基于java串行化机制将流反序列化,并根据RMI协议获取相应的服务端处理对象,进行调用并处理,处理完成后同样基于java串行化机制将数据返回给客户端。
缺点:
1.1 不能跨语言,仅支持Java程序间的通信。
1.2 RMI只能通过RMI协议进行通信,无法通过HTTP协议进行访问,无法穿透防火墙。
1.3 不支持分布式事务JTA。
1.4 RMI框架对于安全性、事务、可拓展性的支持非常有限。
2. XML-RPC
XML-RPC(XML Remote Procedure Call即XML远程方法调用)是一套运行运行在不同操作系统、不同环境的程序实现,基于Internet过程调用规范,这种远程过程调用使用HTTP作为传输协议,XML作为传输信息的编码格式,可以实现跨平台和跨语言。
下面来看XML-RPC的远程通信过程。
1.1 客户端发起请求,按照XML-PRC协议对请求信息进行填充;
1.2 填充后,将xml转化为流,通过HTTP协议进行传输;
1.3 服务端接收到流后将流转化为xml,按照XML-RPC协议获取请求信息,并调用处理类进行处理;
1.4 服务端处理完毕后,将结果按照XML-RPC协议写入XML并返回。
思考问题:
1.1 数据传输的标准格式
标准XML格式。
1.2 基本的数据传输协议
HTTP
1.3 数据与流之间的转化方式
将xml转化为流。
1.4 接受和处理流的方式
通过监听端口获取xml流后转化为xml,并根据协议获取处理等信息,调用处理类处理并将结果写入xml中,采用同样方式返回。
缺点:
1.1 XML-RPC可以发送的数据类型较少,而消息的大小却很庞大。
1.2 XML-RPC缺乏重要的安全机制和健壮的对象模型。
3. Binary-RPC
二进制传输协议。看名字就知道和XML-RPC差不多,不同之处仅在传输的标准格式由XML转为了二进制的格式。
思考问题:
1.1 数据传输的标准格式
标准格式的二进制文件。
1.2 基本的数据传输协议
HTTP。
1.3 数据与流之间的转化方式
将二进制格式文件转化为流传输。
1.4 接受和处理流的方式
服务器通过监听端口获取请求流,转化为二进制格式文件,并根据协议获取处理等信息,调用处理类处理并将结果写入xml返回。
缺点:
1.1 缺乏安全机制,传输没有加密处理。
1.2 Hessian异常信息定位麻烦。之前接触时间类型(Timestamp,为数据库完整保持时间信息)传输时,客户端有时抛异常,根据Hessian提示异常信息,很难定位。后来查找好长时间,才知道:Hessian jar中JavaSesrializier类中,对时间转化时,没有做空判断,导致空指针异常,经包装后,原异常信息丢失。
Try{
Java.util.Date date =(java.util.Date)in.readObject();
Value = newjava.util.Timestamp(date.getTime));
}
Catch(Exception e){….}
4. SOAP
Soap(simple object access protocol 简单对象访问协议)是一个用于分布式环境的、轻量级的,基于XML进行信息交换的通信协议。一条SOAP消息就是一个包含有一个必须的SOAP封装包,一个可选的SOAP消息头和一个必需的SOAP消息体的XML文档。SOAP底层采用HTTP,可以跨平台和跨语言通信。
5. CORBA
CORBA(Common Object Request Broker Architecture 公用对象请求代理提醒结构)是一组用来定义“分布式对象系统”的标准。CORBA定义一套协议,符合该协议的对象可以互相交互,具有语言独立性。
CORBA模型:
Object Services(对象服务):对象服务被分布式对象使用。服务端发布一个可用的服务,需要提供客户端可访问的应用域。CORBA提供2中方式的域对象:The Naming Service和The Trading Service。The Naming Service是客户端通过域名来访问服务。The Trading Services是客户端根据自身的属性来访问服务。
Common Facilities(公共组件):公用组件能被多个应用共享的一系列服务。
Domain Interfaces(领域接口):领域接口类似对象服务和公共组件,主要为特定的应用域而设计。
Application Interfaces(应用程序接口):
CORBA ORB体系结构图:
缺点:
1.1 Corba不能穿透防火墙。Corba监听端口动态变化,如果要穿透防火墙,配置比较复杂。
1.2 CORBA过于复杂。
6. JMS
JMS(Java Message Service)的消息模式
1.1 点对点模式(Point to Point Messaging)
该模型一条信息仅传递给一个接收方。PTP消息传递应用程序使用命名队列发消息。队列发送方向特定的队列发送消息。队列接收方从特定的队列获取消息。一个队列可以有多个发送方和接收方,但一条消息仅传递给一个队列接收方。如果多个队列接受方监听队列上的消息,不同实现采用不同算法确认哪个接收方获取消息,如weblogic JMS采用“先来者优先”算法。如果没有队列接收方监听队列,则消息一直保留在消息队列中,直到队列接收方获取队列为止。
队列(Queue):消息提供方命名的消息队列,消息接收方使用该命名获取消息。
队列链接工厂(QueueConnectionFactory):接收方使用该队列链接工厂创建链接队列(ConnectionQueue),链接队列来获取与JSM点对点消息发送方的链接。
链接队列(ConnectionQueue):活动的链接队列存在消息提供方和消息接收方之间,接收方使用它创建一个或多个JMS消息队列回话(QueueSession)。
队列回话(QueueSession):用来创建消息队列的发送方(QueueSender)和接收方(QueueReceiver)。
消息发送方(QueueSender或MessageProducer):发送消息到已声明队列。
消息接收方(QueueReceiver或MessageConsumer):接受已经被发送到指定队列的消息。
1.2 发布订阅模式(publish – subscribe mode)
该模型支持一条消息传递给多个订阅者。该模型运行多个主题订阅者接受同一条消息。JMS一直保留消息,直到所有主题订阅者都接收消息为止。
主题(Topic):一个消息发送方命名的主题对象,订阅者根据这个主题命名获取主题对象。
主题链接工厂(TopicConnectionFactory):订阅者根据主题链接工厂创建链接主题(ConnectionTopic)来获取与JMS消息pub/sub发布者的链接。
链接主题(ConnectionTopic):一个活动的链接主题存在于发布者和订阅者之间。
主题会话(TopicSession):用于创建主题消息的发布者(TopicPublisher)和订阅者(TopicSubscriber)。
消息发布者(MessageProducer):发送消息到已声明的主题。
消息订阅者(MessageCustomer):接受已经被发送到已指定主题的消息。
缺点:
会遇到安全、事务处理、可伸缩性问题。对于一个简单JMS客户机,您只能选择将安全性和事务处理外包给某个供应商,也就是说,这些问题将是以一种特定于供应商的方式来处理的。如果您的简单JMS客户机既要处理传进来的消息,又要发送消息,那么就会碰到可伸缩性问题。JMS没有能够一次处理多于一个传进来的请求的内建机制。为了支持并发请求,您需要扩展JMS客户机,使其产生多个线程,或者启动多个JVM实例,让这些线程或实例各自运行应用。此外,还需要将JMS提供者配置为在一些适当的目的地上可以有多个订阅者。这时,您就会质疑简单JMS客户机解决方案是否真的具有简单性。
四、 分布式服务框架:
1. RMI
以上已做介绍,具体代码实现请参见《分布式服务框架之RMI》。
2. CORBA
以上已做介绍,具体代码实现请参见《分布式服务框架之CORBA》。
3. Hessian
Hessian将网络传输对象转化为二进制流通过HTTP协议进行传递,采用Binary-PRC协议。可以穿透防火墙。Hessian是轻量级的Remoting on HTTP工具,使用比较简单,与Spring相结合,更加完美。
缺点:
由于Hessian使用自己的序列化机制实现数据的编组(Marshaller)和反编组(UnMarshaller),所以支持的数据类型有限制,不支持复杂类型。
Hessian的代码实现请参见《分布式服务框架之Hessian》。
4. HTTPInvoker
HTTPInvoker是Spring提供的远程通信协议。使用Java序列化机制处理对象的传输。
缺点:
1.1 只能用于Java程序间通信。
1.2 服务端和客户端必须使用SpringFramework。
Spring HTTPInvoker的代码实现参见《分布式服务框架之HttpInvoker》。
5. AXIS
Apache AXIS是一个开源的、基于SOAP的WebService服务架构。
具体代码实现请参见《分布式服务框架之Axis》。
6. Active MQ
Apache ActiveMQ就是基于JMS的实现。
具体代码实现将参见《分布式服务框架之ActiveMQ》。
五、 结尾:
1. 在分布式服务框架的服务端经常需要对客户端发送请求参数进行合法性校验,是否可以抽象接口校验通用方法。比如通过java泛型对参数进行必填项校验、数字型校验、时间类型校验、依赖性校验、合法值集合校验等。
2. 常见的分布式服务框架代码实现介绍正在总结之中,请稍等。