分布式通信协议
- 基于TCP/IP的通信
- 基于对象的通信协议(RPC,CORBA, RMI)
- 基于Http+xml的通信协议(WebService)
- 基于Http的通信协议(Restful)
基于对象的分布式设计
基于Stub/Skeleton的架构分布式对象协议:
- RPC - Remote Procedure
Call
- CORBA - Common Object Request Broker
Architecture
- DCE -
Distributed Computing Environment
- RMI - Remote Method Invocation
- .NET Remoting - .NET Remoting
- DCOM -
Distributed Component Object Model
Reference:
http://en.wikipedia.org/wiki/Distributed_object_communication
基于web的分布式设计
Web Service
Web service是一个平台独立的,松耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的互操作的应用程序。
- UDDI (Universal Description Discovery Integration)
UDDI 提供以标准方式发布,发现Web Service。 - WSDL(Web Services Description Language)
是一个用来描述Web服务和 说明如何与Web服务通信的XML语言,通过WSDL,可描述Web服务的三个基本属性。
1. 服务做些什么 - 服务所提供的操作(方法)
2. 如何访问服务 - 和服务交互的数据格式以及必要协议
3. 服务位于何处 - 协议相关的地址,如URL - SOAP (Simple Object Access Protocol)
SOAP是分布式的环境中交换信息的简单的协议,是一个基于XML的协议。
REST
REST stands for Representational State Transfer.
(It is sometimes spelled "ReST".) It relies on a stateless, client-server, cacheable communications protocol
REST设计概念和准则:
1.网络上的所有事物都被抽象为资源(resource);
2.每个资源对应一个唯一的资源标识(resource identifier)---URL;
3.通过通用的连接器接口(generic connector interface)对资源进行操作 --- HTTP;
4.对资源的各种操作不会改变资源标识;
5.所有的操作都是无状态的(stateless);
Resouce所指的并不是数据,而是数据+特定的表现形式(representation),这也是为什么REST的全名是Representational
State Transfer的原因。举个例子来说,“本月卖得最好的10本书”和“你最喜欢的10本书”在数据上可能有重叠(有一本书即卖得好,你又喜欢),甚至完全相同。但是它们的representation不同,因此是不同的resource。
A real example:
获取XML的response:http://search.twitter.com/search.atom?q=elkstein&count=5
获取JSON的response: http://search.twitter.com/search.json?q=elkstein&count=5
优点:
- 开发容易,是轻量级的SOA
- 提高系统的可伸缩性(Scalability),因为无状态(stateless),服务器的变化对客户端是透明的。
缺点:
- 与SOAP比较,没有类型安全的XML based Request/Response
Reference:
http://rest.elkstein.org/2008/02/what-is-rest.html
http://baike.baidu.com/view/1077487.htm
http://www.infoq.com/cn/articles/rest-introduction
基于消息的分布式设计
优点:
- 通过异步调用,解耦软件组件,增加系统的可用性和可伸缩性(scalability)
- 将可以再后台处理的逻辑从业务逻辑中剥离,增加系统的响应时间
- 对系统请求进行缓冲,从而可以减轻系统面对峰值的压力,因而起到消峰的作用,降低基础设施的投入成本。
- 是SOA的有力补充,对于不能独立完成请求的service,可以通过消息异步调用其他组件协同工作。
- 通过消息实现回调(callback)架构
缺点:
- 实现比同步调用复杂
Reference:
http://www.infoq.com/cn/articles/message-based-distributed-architecture
http://www.infoq.com/cn/articles/ebay-scalability-best-practices
http://www.infoq.com/presentations/shoup-ebay-architectural-principles
异构分布式系统的互操作设计
面向服务的体系结构 SOA (Service-Oriented Architecture)
SOA 是一个组件模型,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来。接口是采用中立的方式进行定义的,它应该独立于
实现服务的硬件平台、操作系统和编程语言。这使得构建在各种这样的系统中的服务可以一种统一和通用的方式进行交互。
SOA的作用
在一个企业内部,可能存在不同的应用系统,而这些应用系统由于开发时间不同,采用的开发工具不同,一个业务请求很难有效地调用所有的应用系统。这些已有的应用系统是孤立的,也就是我们常说的“信息孤岛”, SOA可以实现企业资源共享,打破“信息孤岛”。
基于SOA体系结构的软件开发:http://articles.e-works.net.cn/SOA/Article97034.htm
SOA的主要实现方式 - Web服务(Web Service,REST)
基于面向对象和基于构件的软件开发方法同样遵循复用的概念,但于SOA的复用不同之处是,这种复用是“代码复用”,而SOA是“功能复用”,随着系统复杂的提高,不同的功能模块可能需要用不同的语言编写,或是运行在不同的系统平台上,此时,“代码复用”将无能为力。这并不是说面向对象和基于构建,跟SOA是相冲突的,二者只能选其一。事实恰恰相反,面向对象和SOA往往是有机的融合,一个功能模块,通过SOA来向外部暴露自己所能提供的服务,同时实现这个功能模块又往往会采用面向对象和基于构件的软件开发方法。
SOA设计原则
SOA架构中,继承了来自对象和组件设计的各种原则,如封装,自我包含等。那些保证服务的灵活性、松耦合和重用能力的设计原则,对SOA架构来说同样的非常重要
- 无状态(stateless)。可以提高服务器的可伸缩性。
- 单一功能,避免功能冗余
- 明确定义的接口。使用者依赖服务规约调用服务,所以服务定义必须长时间稳定,一旦公布,不能随意更改;服务定义应尽可能明确,减少使用者的不适当使用。
- 自包含和模块化。服务封装了那些在业务上稳定、重复出现的活动和组件。实现服务的功能实体是完全独立自主的,独立进行部署,版本控制,自我管理和恢复。
- 粗粒度。服务数量不应该太大
- 服务之间的松耦合性。服务使用者看到的是服务的接口,其位置,实现技术和当前状态等对使用者是不可见的。
- 重用能力。服务应该可以被重用
- 互操作性,兼容和策略声明。
从耦合度看软件技术的发展
耦合度是模块之间的联系程度,模块间联系越紧密,耦合度越强,模块独立性越差;联系越少,耦合度越低。简而言之就是我对你知道的越少,我对你的依赖越少,从而耦合度越低。
若对耦合进行分类,数据耦合的耦合度最低即一个模块对另一个模块的访问时通过简单的数值参数,内容耦合的耦合度最高。
松耦合具有更大的灵活性(Flexibility) ,可扩展性(Extensibility)和复用性(Re-usability),因为调用者和被调用者之间的耦合度低,所以交互双方均能比较独立的变化,而对彼此造成的影响很小或不造成影响,不至于动一发而动全身。
在面向过程的编程中,主程序是通过调用子程序的方法来完成协作的,这种“过程”依赖无疑是耦合度非常高的,因为子过程的任何变化都会引起主程序的变化,而且更换子过程也是一件非常麻烦的事情。转向面向对象的编程技术后,利用对象的封装特性,把数据和不需要被应用的方法通过私有化定义隐藏在类中,从一定程度上减轻了调用者和被调用者之间的耦合度,并且因为对象具有继承和多态性,利用依赖倒转技术(面向接口编程)使得在运行时使用不同语义的方法成为了可能,极大地增加了灵活性和可扩展性。
但是对对象的使用,并不是凭空产生的,首先需要创建一个对象,最原始的方式就是我需要使用一个对象就 new ObjectA(),这是耦合度最高的一种方式,因为对象调用者不仅要知道被调用对象的方法,还要知道被调用对象的创建方式。有没有一种方式,能将对象创建从对象使用中解耦出来呢?有的,工厂方法,让工厂去创建对象,调用者无需自己去创建对象了,而是委托工厂去创建,这种解耦的好处是,如果需要替换对象,只需要更改工厂,而所有引用该对象的代码都可以保持不变。工厂方法虽然比直接new一个对象好,但是ObjectA作为一个标记,还是要出现在工厂里,这样工厂和ObjectA还是紧耦合的,那么有没有一种方式让ObjectA不要出现呢?
有,依赖注入(Dependency Injection),就是在程序中不需要显示的标明所要依赖对象的名字,而是通过配置文件,以一种注入的方式将所依赖的类提供给类的调用者。
至此,在面向对象中解耦已经达到一个比较满意的程度,再进一步的解耦也不会带来多大的收益,但是对象只能是在一台JVM中,不能满足分布式环境的需求,OMG提出了分布式对象请求代理架构(CORBA),在这个远程调用中,服务的描述(IDL)需要和编程语言进行绑定,例如如果基于JAVA的CORBA实现,这需要一个Java IDL bridge,这也是紧耦合的一种表现。
那么,能不能使用一种更中立的方式来定义我们分布式应用中的接口呢?是的,Web service使用WSDL来定义自己的服务,而WSDL是用XML语言的,XML是平台独立、编程语言独立的文本格式,也就是说一个WS客户端对WS服务器的依赖仅仅是一份XML文档而已,并且客户端和服务器端之间的通信也是采用普遍存在和广泛支持的HTTP,因此Web Service 是一种耦合度很低的RPC,对WSDL文档依赖也是一种耦合度的表现。
REST是一种轻量级的基于Web的分布式架构风格,其将HTTP作为一种特殊的应用协议(在WS中,HTTP仅仅是传输协议,消息载体是SOAP),利用现有的Web平台和HTTP特性,可以构建出更简单、可伸缩性更好的Web服务,其客户端对服务器端的依赖仅仅是一个资源标识(URI ),而内容表述可以是XML、JSON、TXT甚至是图片、视频等任意格式,因此REST是比WS耦合度更低的,再次强调,耦合度越低,可扩展性越好,看看今天无比强大和丰富的Web,足以证明REST这种松耦合性能够满足几乎所有的应用需求。