`
youxinrencwx
  • 浏览: 67300 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

基于SCA规范的服务框架设计与实现

 
阅读更多

基于SCA规范的服务框架设计与实现

Author: 岑文初

Email: wenchu.cenwc@alibaba-inc.com

Version: 0.1

Date: <chsdate style="BACKGROUND-POSITION: left bottom; BACKGROUND-IMAGE: url(res://ietag.dll/#34/#1001); BACKGROUND-REPEAT: repeat-x" w:st="on" isrocdate="False" islunardate="False" day="1" month="7" year="2007">2007-07-01</chsdate>

概述... 2

SCA的简单介绍... 3

SCA & OSGI 4

Tuscany, First Demo. 5

Mail Composite Demo. 5

基于Tuscany实现内嵌服务框架定制... 9

一点感想... 10


概述

SCAService Component Architecture)是针对SOA提出的一套服务体系构建框架协议,内部既融合了IOC的思想,同时又把面向对象的复用由代码复用上升到了业务模块组件复用,同时将服务接口,实现,部署,调用完全分离,通过配置的形式灵活的组装,绑定。

从代码级的面向对象思想,到组件级的EJB概念,再到服务级的SOA理念,是一个开发复用的不断提升的过程,经历的经验教训正在给实践做出最好的指导。SOA提倡的就是更高级别的复用,服务的复用,Internet提供了开放的环境,但是没有一种统一的服务访问模式,让各个企业之间成了信息内部丰富的孤岛,需要将这些孤岛串联起来,同时要最大限度的复用有限的资源,因此提出了面向服务概念,但是多年的SOA口号下却缺少着一个真正的实施标准和解决方案,因此SOA的理论传播大于实际实施。

SCASDO的出现,给SOA来了点实际的。SCAService Component Architecture)其实就是将过去EJB的成果继续下去,基于Component的复用,同时吸收了IOC的思想,Component之间的组装是通过SCA框架来实现的,但是很重要的一点,他没有走EJB的老路,而是学习spring的轻量级框架,不再为开发者作的面面俱到。SCAComponentOSGIBundle一样其实是对Java封装的一种贯彻,它有需要Import的服务引用,需要Export的服务,很重要一点就是它对于Componentservice,reference的实现都没有作限制,这类对象只需要有个接口定义和实现描述即可,当前规范中支持的接口定义可以是java接口也可以是wsdl文件(最终也是转换成为java接口),实现的话那么更加广泛java,webservice,rmi,jms,脚本语言等等,同时提供了扩展接口。


SCA的简单介绍

OSOAOpen Service Oriented Architecture)针对SOA实现提出了一系列技术框架规范,其中包括了两大部分:SCAService Component Architecture)和SDOService Data Objects)。SCA旨在解决使用各种不同的实现来创建面向服务的组件,以及如何将创建的组件装配和发布,满足业务流程需求的开发和部署。SDO提供给应用开发一套完整的数据处理方案,数据源及其格式将对应用处理透明。这两者可以分开使用也可以一起配合使用。http://www.osoa.org/display/Main/Home SCA的官方网站,里面现在提供了两部分项目的规范定义文件。

SCA最基本的结构单元就是ComponentSCA Composite将多个Component包含定义在内,组成了完整的业务模块单元。下面就是Component基本结构单元的结构图,后面会对这个基本单元的各个部分作详细的描述:

<shapetype id="_x0000_t75" stroked="f" filled="f" path=" m@4@5 l@4@11@9@11@9@5 xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0 "></f><f eqn="sum @0 1 0 "></f><f eqn="sum 0 0 @1 "></f><f eqn="prod @2 1 2 "></f><f eqn="prod @3 21600 pixelWidth "></f><f eqn="prod @3 21600 pixelHeight "></f><f eqn="sum @0 0 1 "></f><f eqn="prod @6 1 2 "></f><f eqn="prod @7 21600 pixelWidth "></f><f eqn="sum @8 21600 0 "></f><f eqn="prod @7 21600 pixelHeight "></f><f eqn="sum @10 21600 0 "></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 414.75pt; HEIGHT: 257.25pt" coordsize="21600,21600" type="#_x0000_t75"><imagedata o:title="" src="10C657F8.files/image001.emz"></imagedata></shape>

1 SCA Component结构图

Composite通常都有一个xxx.composite文件用来描述Composite的结构以及每一个Component的实现,接口,服务,引用的定义。

<shape id="_x0000_i1026" style="WIDTH: 414.75pt; HEIGHT: 495.75pt" coordsize="21600,21600" type="#_x0000_t75"><imagedata o:title="" src="10C657F8.files/image003.emz"></imagedata></shape>

2 SCA Composite结构图

SCA & OSGI

基于OSGI的开发首先要求就是基于接口开发,任何业务模块的开发,都需要将业务操作抽象成为一系列的接口定义(通常就成为最基本的Interface Specification Bundle),业务间的调用都是通过接口调用来实现的,也支持IOC来注入接口。

<shape id="_x0000_i1027" style="WIDTH: 415.5pt; HEIGHT: 236.25pt" coordsize="21600,21600" type="#_x0000_t75"><imagedata o:title="" src="10C657F8.files/image005.emz"></imagedata></shape>

3 OSGI 模块间交互情况

OSGI容器类似于Spring容器,负责装载以及装配各个定义好的Bundle,各个Bundle都有自己的importexport的接口包,具体的实现对彼此都是透明的,容器支持动态的装载和卸载各个实现Bundle的,这样就做到了对业务无影响的情况下就可以切换不同的业务实现。同时接口化编程能够被更好的贯彻,模块与模块之间只能通过模块间的业务接口来互相访问对方的业务信息,降低了耦合度。

但是也可以看出OSGI适合单机部署的应用开发,其实就本身OSGI的设计初衷就不是考虑跨服务器多机部署的情况,因此不适合作为平台的服务框架。但是对于需要单机部署的一些特殊业务实现(例如Job服务,当前实现了Job接口的定义以及Quartz的实现)就可以采取这种方式,不过如果不是需要切换实现,那么不是很体现的出OSGI的特性。

记得在论坛上有人讨论过SCAOSGI的优劣,但其实作为这两个规范面向的解决问题都是不同的,SCASOA的一个实现,SOA是解决分布式服务的互通问题,而OSGI是针对单机服务的动态绑定义及组装,因此两者不存在着可比性,但是在我看来,两者却有着很好的互补性,在平台的现有情况下,用SCA来实现服务框架,同时通过OSGI来实现组件装配,这无疑是很好的一件事情。

<place w:st="on"><state w:st="on"><span style="mso-bookmark: _Toc174870168"><span lang="EN-US" style="FONT-SIZE: 15pt; LINE-HEIGHT: 240%; mso-bidi-font-size: 22.0pt">Tuscany</span></span></state></place>, First Demo

OSOA提出的SCA只是一个规范,因此包括BEAIBM等大公司的平台都有相应的技术实现,而TuscanyApache孵化项目中的一个实现了SCA,SDO的规范的开源项目(http://incubator.apache.org/tuscany/home.html)。最新的版本是基于SCA 规范 v1.0版本而实现的SCA Java 0.90-incubating,当然它还提供了C++的版本。

Mail Composite Demo

开发SCA的组件和java开发普通的业务模块没有什么区别,只是在业务逻辑代码开发完以后需要将逻辑实现以及需要发布和引用在配置文件中定义和描述。下面分别是MailCompositeJava类图以及SCA组件的结构图。

<shape id="_x0000_i1028" style="WIDTH: 381pt; HEIGHT: 319.5pt" coordsize="21600,21600" type="#_x0000_t75"><imagedata o:title="" src="10C657F8.files/image007.emz"></imagedata></shape>

5 Mail Composite的基本类图

<shape id="_x0000_i1029" style="WIDTH: 417pt; HEIGHT: 459.75pt" coordsize="21600,21600" type="#_x0000_t75"><imagedata o:title="" src="10C657F8.files/image009.emz"></imagedata></shape>

6 Mail Composite组件结构图

Mail.composite具体的内容如下:

<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" targetNamespace="http://mail"

xmlns:wsdli="http://www.w3.org/2004/08/wsdl-instance" name="Mail" >

<!—- 组件级别的服务定义,这个定义可以被不同的composite引用,也就是它的作用域为服务框架,promote表示这个服务由内部哪个具体的component或者component级别的service实现,也就是这里只是一个声明的部分,实现参看最后的MailCustomerComponent -->

<service name="MailCustomerService" promote="MailCustomerComponent"/>

<component name="MailComponent">

<implementation.java class="com.alisoft.sample.tuscany.MailServiceImpl"/>

<!— service标签是component级别的服务,内部可以组装,但是无法跨composite,作用域为composite -->

<service name="MailService">

<!-- 服务接口描述 -->

<interface.java interface="com.alisoft.sample.tuscany.MailService"/>

</service>

<!—- 组件的引用,可以是另一个component也可以是component级别的service -->

<reference name="postOfficeService" target="PostOfficeComponent"/>

</component>

<component name="PostOfficeComponent">

<implementation.java class="com.alisoft.sample.tuscany.PostOfficeServiceImpl"/>

</component>

<component name="RetailStoreComponent2">

<implementation.java class="com.alisoft.sample.tuscany.RetailStoreServiceImpl"/>

</component>

<component name="RetailStoreComponent">

<service name="RetailStoreService">

<!—- 发布成为webservice的服务,设定绑定的地址,需要有wsdl文件的配合(将wsdl描述文件打入包,接口的描述可以是wsdl,也可以是java类型的接口) -->

<interface.wsdl interface="http://mail#wsdl.interface(RetailStoreServicePortType)" />

<binding.ws uri="http://localhost:8085/RetailStoreService"/>

</service>

<implementation.java class="com.alisoft.sample.tuscany.RetailStoreServiceImpl"/>

</component>

<!—Composite级别的reference,指明是提供给谁的这里是提供给MailComponentretailStoreService的,绑定的是内部那个发布成为webservicecomponent,注意component内部可以作为组装对象 -->

<reference name="RetailStoreReference" promote="MailComponent/retailStoreService">

<interface.java interface="com.alisoft.sample.tuscany.RetailStoreService"/>

<binding.ws wsdlElement="http://mail#wsdl.port(RetailStoreService/RetailStoreServiceSOAPPort)"/>

</reference>

<component name="MailCustomerComponent">

<implementation.java class="com.alisoft.sample.tuscany.MailCustomerService"/>

<reference name="customerService"/>

</component>

<!—- 这是Composite级别的引用,需要通过promote指定是提供给哪个具体Component的引用,promote表示的就是提供给哪一个Component的引用,target表示需要和服务框架中Composite级别的服务关联的名字,这里也就是和上个例子中的一个Composite级别的服务连接 -->

<reference name="customerServiceReference" target="CustomerService" promote="MailCustomerComponent/customerService">

</reference>

</composite>

接下去就要配置一下依赖的Tuscanyjar了,两种方式:一种就是通过svn下载当前Tuscany所有的源码工程,然后让这个项目依赖于那些工程(最好使用这种方式,因为方便调试)。另一种方式就是将下载下来的发布包内lib里面的tuscany-sca-all-0.90-incubating.jartuscany-sca-manifest.jar作为第三方依赖。

最后就是写一下MailClient的代码,很简单的几句话:

SCADomain scaDomain = SCADomain.newInstance("Mail.composite");

if (scaDomain == null)

System.out.println("SCADomain is null");

System.out.println("start SCADomain now");

MailService mailService = scaDomain.getService(MailService.class, " MailCustomerService");

mailService.sendMail();

scaDomain.close();

System.out.println("end scaDomain");

基于Tuscany实现内嵌服务框架定制

Tuscany提供了对外可嵌入的SCADomain(服务组装和发布的容器)叫做EmbeddedSCADomain,下图展示的是EmbeddedSCADomain的结构:

<shape id="_x0000_i1030" style="WIDTH: 368.25pt; HEIGHT: 272.25pt" coordsize="21600,21600" type="#_x0000_t75"><imagedata o:title="" src="10C657F8.files/image011.emz"></imagedata></shape>

7 Tuscany实现的EmbeddedSCADomain的结构

从上图来看,首先EmbeddedSCADomain内部内嵌了一个DomainComposite,这是一个虚的Composite,作用就是提供一个将所有Composite载入和组装的对象,由于SCA规范中规定CompositeA include CompositeB,那么CompositeA可见CompositeB内所有的componentservice。这也就是说DomainComposite其实将所有部署在Domain中的Composite先全部平面化,然后再进行组装。这就出现了问题:一. 对于DomainComposite中某一个Composite的停止和载入将无法控制。二. 由于多个Composite被平面化,导致每个Composite内部的封装被破坏,每个Composite都可以调用其它Composite没有发布成为服务的业务逻辑。三.由于DomainComponent都被放置到Components,同时都可被访问,因此失去了对外的封装性。

同时,Tuscany本身实现上还有问题,在规范中明确指出了服务和引用存在两种Component级别的和Composite级别的,具体的结构如下:

<shape id="_x0000_i1031" style="WIDTH: 372pt; HEIGHT: 171pt" coordsize="21600,21600" type="#_x0000_t75"><imagedata o:title="" src="10C657F8.files/image013.emz"></imagedata></shape>

8 Composite的两种级别的ServiceReference

Component级别的服务之能够在Composite内被引用,Composite的服务其实是指定了一个内部的服务,然后允许发布到Composite以外,提供给其他的Composite调用。Component 级别的reference通过查找Composite内部的服务或者是实现来达到组装的目的,Composite级别的reference通过查找外部的服务来组装,Composite单独定义,可以promote给多个内部的reference。但是这两部分内容Tuscany都没有做到,需要通过自定义容器的组装来实现。

因此平台的服务Domain定义结构如下,同时需要修复Composite的组装问题。

<shape id="_x0000_i1032" style="WIDTH: 414.75pt; HEIGHT: 172.5pt" coordsize="21600,21600" type="#_x0000_t75"><imagedata o:title="" src="10C657F8.files/image015.emz"></imagedata></shape>

9 ServiceSCADoman结构图

所有的Composite独立被管理和加载,同时Composite的装配以及互通严格遵循SCA的规范。外部调用SCADomain内的服务,只能是发布成为Composite的服务。

一点感想

SCA处于起步阶段,开源项目正在不断完善中,但是就SCA规范本身来说,对于未来的SOA是一种很好的推动,同时也为将来服务级的复用提供了具体的解决方案,使用SCA的规范来构建服务框架还需要不断的去扩展和改进,并且结合Spring,OSGI等好的开源工具和规范思想能够有更广阔的发展空间。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics