SOA简述

混沌

接触SOA也有几年时间了,从未对其概念和模式深究。我们总是对自己每天接触的东西习以为常,甚至视而不见。随着互联网的发展,SOA的架构也随之大行其道,随之而来的是各种高大上的架构模型和技术名称,林林总总让人眼花缭乱。一直以来对这些都是模糊的概念,想去深究也屡不出个头绪。最近看了几篇业界大牛的文章,略有感悟,试着整理下思路,理清一些基本的概念和术语。本文侧重以自己的理解描述SOA是什么以及由SOA衍生而来的各种技术名词和他们之间的关系,不会详细阐述SOA的原理和SOA架构的各种实践。

开悟

SOA定义

  • 先来一段维基百科对SOA的描述

    面向服务的体系结构(英语:service-oriented architecture)是构造分布式计算的应用程序的方法。它将应用程序功能作为服务发送给最终用户或者其他服务。它采用开放标准、与软件资源进行交互并采用表示的标准方式。

    怎么样,多么标准的教科书般的定义。不过这个定义未免太过抽象,我们试着从实质的内容来阐述一下,SOA的出现是为了解决一种什么样的问题或者他规定了什么内容。

  • 感性的SOA定义
    SOA不是一种技术,也不是一个标准,而是一种架构方式,包含了服务提供者、服务调用者、服务管理中心等角色,整个架构模式也是围绕着这些角色如何更有效的互相配合,从而实现SOA架构的商业价值。SOA的应用已经非常普及,毕竟从诞生到现在已经二十余年了。1996年由Gartner公司提出,后经过IBMSUNBEAOracle等公司完善和推广,SOA的思想和理论逐步得到完善。不管是从概念模型上还是具体应用技术上,都已经得到了全面的发展,也衍生出了很多的新的概念和技术,比如HTTP API,云服务,敏捷开发,持续交付,DevOps等,这些技术的发展和成熟也推动着SOA架构的不断演变。

    SOA理念

    SOA要求开发者从服务集成的角度来设计应用软件,目标为了提高重用性,即使这么做的利益不会马上显现。SOA要求开发者超越应用软件来思考,并考虑复用现有的服务,或者检查如何让服务被重复利用。SOA鼓励使用可替代的技术和方法(例如消息机制),通过把服务联系在一起而非编写新代码来构架应用。

    SOA原则

    服务松耦合(Loosely coupled) - 服务之间的关系最小化,只是互相知道。
    服务契约 - 服务按照服务描述文档所定义的服务契约行事。
    服务抽象 - 除了服务契约中所描述的内容,服务将对外部隐藏逻辑。
    服务的重用性 - 将逻辑分布在不同的服务中,以提高服务的重用性。
    服务的可组合性 - 一组服务可以协调工作并组合起来形成一个组合服务。
    服务自治 – 服务对所封装的逻辑具有控制权
    服务无状态 – 服务将一个活动所需保存的资讯最小化。
    服务的可被发现性 – 服务需要对外部提供描述资讯,这样可以通过现有的发现机制发现并访问这些服务。

这样,我们对SOA有了一个感性的了解,我们可以这样认为,SOA其实就是利用模块化思维,遵循SOA定义的原则构建分布式应用的架构模式,基于这个理解下面我们再来看一下在SOA架构下的实现方式。

实现

Web Service

Web Service相信大家对这个名词也不是很陌生吧,不过令人遗憾的是这个现在已经被滥用的太严重了,以至于我们不能清晰的描述出Web Service到底是什么。老规矩,根据维基百科定义Web服务是一种服务导向架构的技术,通过标准的Web协议提供服务,目的是保证不同平台的应用服务可以互操作。 其实,一般情况下可以认为Web serviceSOA架构的一个实例,通常使用HTTP协议,一般使用web服务器作为服务请求的管道。

  • Web Service要素

    • SOAP
      提到Web Service,不得不说到的就是SOAP了。SOAP(原为Simple Object Access Protocol的首字母缩写,即简单对象访问协议)是交换数据的一种协议规范,一个基于XML的可扩展消息信封格式,需同时绑定一个网络传输协议。这个协议通常是HTTPHTTPS,但也可能是SMTPXMPP

    • WSDL
      WSDL (Web Service Description Language)也遵循XML格式,用来描述哪个服务器提供什么服务,怎样找到它,以及该服务使用怎样的接口规范,简言之,服务发现。

    • UUID
      一个用来发布和搜索WEB服务的协议,应用程序可借由此协议在设计或运行时找到目标WEB服务。
  • 不同厂商的实现
    不同的厂商根据又发展了自己的协议和实现方式

    • java
      Java API for XML Web Services(JAX-WS)Java程序设计语言一个用来创建Web服务的API
    • .NET
      .NET WebServiceNET RemotingWCF
  • Web Service 使用
    使用Web Service的过程变成,获得该服务的WSDL描述,根据WSDL构造一条格式化的SOAP请求发送给服务器,然后接收一条同样SOAP格式的应答,最后根据先前的WSDL解码数据。绝大多数情况下,请求和应答使用HTTP协议传输,那么发送请求就使用HTTP的POST方法。不过现在为了简化调用过程,又有了新的使用方式,就是舍弃一部分或者完全舍弃SOAP协议,使用HTTP+去掉头尾的SOAP或者HTTP+JSON的方式调实现web service,这种更加轻量的方式又叫做rest方式调用。

Rest

  • 又又又来一个新名词

REST(英文:Representational State Transfer,又称具象状态传输)是Roy Thomas Fielding博士于2000年在他的博士论文中提出来的一种万维网软件架构风格,目的是便于不同软件/程序在网络(例如互联网)中互相传递信息。说到底,REST也只是一种架构风格,而不是协议或标准。但这种新的风格对现有的以SOAP为代表的Web Service造成的冲击也是革命性的,因为它面向资源,甚至连服务也抽象成资源,它和HTTP紧密结合,是无状态的。

传统意义上的rest可能要和soa划在一个层面,都是软件架构的方式,soa是面向服务的软件架构方式,Rest是面向资源的软件架构方式,不过事实上,一些Web Service提供者提供的REST API只有REST的外壳,传输的请求和应答全然是简化了的SOAP,这种新瓶装旧酒的做法只是加深了标准的分歧而已。归根结底REST无法简单地解决一些问题,因此我们只能看到SOAP在REST外壳下的借尸还魂。所以目前rest还是划分到webservice下的一个使用方式的分支,用以区分以soap为协议的传统webservice的调用方法。

通信

分布式异构系统的通信

上面说到了SOA是构建模块化的分布式系统的架构模式,既然提到了分布式,那不得不说的就是基于分布式的模式下各个系统或者模块间的通信了。SOA建立在分布式和异构平台下,分布式程序的基础是RPC调用,RPC的本质是网络传输和对象序列化,需要用RPC在分布式和异构系统中进行通信。当然这只一种选择,还可以选择比如基于message的方式进行通讯和集成,这里就不展开说明了。

RPC

维基百科对于RPC的定义
远程过程调用(英语:Remote Procedure Call,缩写为 RPC)是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外地为这个交互作用编程。如果涉及的软件采用面向对象编程,那么远程过程调用亦可称作远程调用或远程方法调用,例:Java RMI。

  • RPC目标
    RPC的主要目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性。 为实现该目标,RPC框架需提供一种透明调用机制让使用者不必显式的区分本地调用和远程调用。
  • RPC性能
    不过RPC是跨进程进行调用,如果在进程内进行方法调用,所需的时间量级是 ns(纳秒)级,而进程间的RPC方法调用时间量级通常是 ms(毫秒)级,它们之间有着10的六次方的效率之差,所以选择这只方式进行通讯意味着要要牺牲一定的性能,而且一般在这种架构下完成一个功能或者一个接口可能需要多次的RPC调用,这就要求我们在实现接口是特别注意性能问题,一点点的性能差异在这种架构下都会被放大。

分布式服务框架

业界主流框架

上面提到针对SOA的实现,各大厂商都提供了自己的技术实现和一整套的解决方案,但是在大规模异构的分布式系统中,还是希望能有一个比较统一的框架来实现各种异构系统的通信和集成,这个时候,就有了各种RPC框架,或者叫服务框架。一般分为两种,一种是比较狭义的RPC框架,属于轻量级框架,仅具备完整的RPC调用功能(比如像thriftgRPC等),在各种复杂的架构和业务场景下,这种框架显得有些捉襟见肘,不具备比如调用监控、服务路由等功能。这时候,又衍生出了另外一种框架,分布式服务框架,包括RPC调用、服务治理、注册发现、流量切换、服务路由、多传输协议、多序列化协议等各种复杂的功能,使得SOA架构下的分布式系统具备高可用的能力。

多语言支持

CORBAR为了解决异构平台的RPC,使用了IDL(Interface Definition Language)来定义远程接口,并将其映射到特定的平台语言中。后来大部分的跨语言平台RPC基本都采用了此类方式,比如我们熟悉的Web Service(SOAP),近年开源的 Thrift等。他们大部分都通过IDL定义,并提供工具来映射生成不同语言平台的user-stubserver-stub,并通过框架库来提供RPCRuntime的支持。不过貌似每个不同的RPC框架都定义了各自不同的IDL格式,导致程序员的学习成本进一步上升,Web Service尝试建立业界标准,无赖标准规范复杂而效率偏低,否则Thrift等更高效的RPC框架就没必要出现了。IDL 是为了跨平台语言实现RPC不得已的选择,要解决更广泛的问题自然导致了更复杂的方案。而对于同一平台内的 RPC 而言显然没必要搞个中间语言出来,例如Java原生的RMI,这样对于java程序员而言显得更直接简单,降低使用的学习成本。

参考

http://www.cnblogs.com/mindwind/p/5518145.html
https://zh.wikipedia.org/wiki/%E9%9D%A2%E5%90%91%E6%9C%8D%E5%8A%A1%E7%9A%84%E6%9E%B6%E6%9E%84
http://www.baike.com/wiki/SOA%E6%9E%B6%E6%9E%84
https://segmentfault.com/q/1010000003049016
http://www.infoq.com/cn/articles/micro-soa-2?utm_source=infoq&utm_campaign=user_page&utm_medium=link
http://www.infoq.com/cn/articles/micro-soa-1?utm_source=infoq&utm_campaign=user_page&utm_medium=link
http://itindex.net/detail/51931-soa-api-%E5%88%86%E8%A3%82
http://www.cnblogs.com/zhangz721/archive/2009/10/02/1577316.html

如若在茫茫宇宙中窥见了一丝真理,那该是何等之幸事。