BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

使用绑定实现灵活通信

| 作者 Anthony Elder 关注 0 他的粉丝 , Simon Nash 关注 0 他的粉丝 , Raymond Feng 关注 0 他的粉丝 , Simon Laws 关注 0 他的粉丝 , Haleh Mahbod 关注 0 他的粉丝 ,译者 马国耀 关注 1 他的粉丝 发布于 2009年8月26日. 估计阅读时间: 21 分钟 | 都知道硅谷人工智能做的好,你知道 硅谷的运维技术 也值得参考吗?QCon上海带你探索其中的奥义

这篇文章节选自《Apache Tuscany in Action》,它介绍了如何使用绑定进行组件服务连接的配置。

SCA最重要的特征之一是对交互协议的广泛支持。如果你的服务要同Web服务、JMS、CORBA或者REST交互的话,通过SCA和Tuscany就可以轻松做到。如果因为特定应用的需要,服务使用特殊的或私有的协议进行通讯的话,SCA也没有问题。甚至,你的业务逻辑根本不需要知道交互协议是什么,(没错,你已经猜对了)协议的选择是通过对组件的配置实现的。这太酷了,不是吗?而SCA绑定就是让这一切成为可能的“魔力”。

在这篇文章中,我们将了解如何在服务以及引用上使用绑定;此外,如果没有配置绑定话,意味着什么;最后,我们还要去看看SCA的域,去了解如何在SCA域内和域外运用绑定。

为服务和引用配置绑定

你可以在服务以及引用上配置绑定。为服务设定一个绑定意味着人们可以通过由该绑定所指定的交互协议来访问这个服务。而服务的实现不需要做任何特别的改变来促成这个目标,你要做的仅仅是为服务增加一条绑定配置。

例如,如果要让Bookings服务以Web服务的方式暴露出来,那么组件的定义看起来就应该是这样的:

<component name="TripBooking">
  <implementation.java class="com.tuscanyscatours.TripBooking" />
  <service name="Bookings">
    <binding.ws uri="http://tuscanyscatours.com:8085/Bookings" />
  </service>
</component>

我们通过增加<binding.ws>元素告诉SCA运行时,Bookings服务要以Web服务的形式暴露出来,使用SOAP/HTTP的 方式,并且以uri属性中指定的值作为服务的端点(endpoint)。这就是要创建Web服务我们要做的全部事情,无需学习JAX-WS或者在 Bookings服务的实现上做文章。

可以为一个服务配置多个绑定。如果既要通过JMS访问又要通过Web服务方式来访问Bookings服务,则只需要增加另一条绑定。请看下面的例子:

<component name="TripBooking">
  <implementation.java class="com.tuscanyscatours.TripBooking" />
  <service name="Bookings">
    <binding.ws uri="http://tuscanyscatours.com:8085/Bookings" />
    <binding.jms />
  </service>
</component>

这个定义让Bookings服务同时以JMS的方式暴露出来,并且使用了缺省配置。同样,我们不需要去学习JMS的API或修改服务的实现代码。

绑定还将SCA和Tuscany与更广阔的外部世界联系起来!Bookings服务是以SCA实现,运行在Tuscany中的。由于使用绑定对这个服务进行了配置,它可以被以非SCA方式实现的客户端或运行在Tuscany中的客户端调用。对于Bookings的Web服务调用,客户端可以是任何语言编写的,运行在任何遵循WS-I的Web服务运行时上的程序;同样,对于JMS方式的调用,客户端可以直接使用任何JMS提供者所提供的JMS API,只要该JMS提供者与Tuscany中配置的JMS绑定对应的JMS提供者兼容即可。

现在我们已经看到如何通过在SCA的服务上配置绑定让服务以标准的交互协议向外提供服务。同样,绑定也可以用于SCA引用上,让其通过标准的交互协议去调 用外部服务。这种情况下角色正好倒置:客户端由SCA实现,而服务端使用标准的交互协议。例如,服务提供者可能是一个支持SOAP/HTTP的Web服务 端点,也有可能是一个以RMI-IIOP方式交互的EJB(session bean)。与Web服务交互时,SCA引用使用<binding.ws>绑定;而调用EJB时,它使 用<binding.ejb>绑定。

图1显示了如何在组件的服务以及引用上配置绑定。

图1:Bookings服务配置了Web服务和JMS的绑定,“cars”引用配置了Web服务绑定,“flights”引用配置的是EJB绑定。

列表1中的示例代码显示的是图1中描绘的TripBooking组件对应的组件定义文件。

列表1 为组件的服务和引用配置绑定和连线

<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
	targetNamespace="http://tuscanyscatours.com/"
	name="bookings">
    <component name="TripBooking">
      <implementation.java class="com.tuscanyscatours.TripBooking" />
      <service name="Bookings">
	<binding.ws uri="http://tuscanyscatours.com:8085/Bookings" />
	<binding.jms />
      </service>
      <reference name="cars">
	<binding.ws uri="http://tuscanycars.com:8081/Cars" />
      </reference>
      <reference name="flights">
	<binding.ejb uri="corbaname:rir:#flight/FlightProviderHome" />
      </reference>
      <reference name="hotels" target="HotelProvider" />
    </component>
</composite>

你可能已经发现列表1中有两个引用(cars和flights)配置了绑定而没有target属性,这是因为该绑定元素已经提供了引用的目标端点信息,同时还指定了所使用的交互协议。

至此,我们已经了解如何在服务和引用上使用绑定。在下一节中,我们要看看如果在服务和引用的配置中不指定绑定将会发生什么?

缺省绑定

在列表1中我们为“hotels”引用没有设置绑定,这意味着它有一个隐含的.sca绑定(经常被称为缺省绑定)。缺省绑定用于连接SCA服务和SCA引用,把交互技术的选择工作交给部署服务和引用的SCA运行时,而其他的绑定(如WS绑定和JMS绑定)则要选择具体的交互协议或API,从而让SCA服务或引用可以与非SCA的程序进行交互。正因为如此,非缺省的绑定通常被称为可互操作的绑定。

Tuscany使用基于SOAP/HTTP的Web服务实现缺省绑定的远程调用;其他的SCA运行时可能使用不同的标准协议,如RMI/IIOP,它们也 可以使用某种私有协议。将来,Tuscany的缺省绑定的通讯协议也可以从Web服务转向其他的协议,因此,Tuscany的应用程序不应该想当然地假设 使用缺省绑定就意味着使用Web服务。应用程序若要使用Web服务在组件之间交互的话,为保险起见,还是应该要指定使 用<binding.ws>绑定。

缺省绑定只能用于连接位于同一个SCA中的服务和引用,而当连接跨越域边界时,应该要为其指定某个可互操作的绑定。域在SCA中是一个重要的概念,我们将在第四章详细介绍域的概念,不过在下一个节中我们先简单介绍一下什么是域以及它与绑定和连线的关系。

域,绑定和连线(wire)

SCA域是一个SCA组件的部署和管理边界,比如,一个域可能是单个应用服务器或一个服务器集群,也可以是一组服务器或一组集群。而一个完整的域通常只运行某一家提供商的SCA实现。

任何SCA组件都是SCA域的一部分;同一域中的服务和引用可以通过连线进行连接;对于同一域中的服务和引用之间的连接,可以使用缺省绑定,因为SCA保证了缺省绑定的实现在域中的一致性。相反,对于域内到域外的交互,不能使用连线进行连接,而应该使用可互操作的绑定。

在第2章我们已经介绍了TuscanySCATours公司,下面我们将通过该公司的一个场景来描述域的使用。现在,这个公司已经壮大,并且设立了一个独 立的部门提供专门的hotel booking(酒店预订)服务。这个服务不仅要服务于TuscanySCATours的trip booking(行程预订)服务,还要直接服务于只需预订酒店的客户。公司的两个部门使用不同的域管理他们所提供的服务:TuscanySCATours 域提供原先的trip booking(行程预订)服务,而TuscanySCAHotels域提供新的hotel booking(酒店预订)服务,如图二所示:

图2中有两个SCA域及多个组件,展示了组件是如何连接的,连线(实线)用于连接同一域中的组件,而 绑定(带箭头的虚线)用于连接跨域的组件。

图2中用实线表示连接组件的SCA连线,而用带箭头的虚线表示用可互操作的绑定配置的连接。我们先来看看TuscanySCATours域中 TripBooking组件的3个引用。首先,flights(航班)引用连到一个实现flights预定的Web 服务,因为这个服务不是SCA服务,所以flights引用通过可互操作的绑定<binding.ws>和flights预订服务的URI进 行配置。

其次,“hotels”引用指向了TuscanySCAHotels域中的由HotelProvider这个组件所提供的Hotels服务。由于连线不能 跨越域的界限,所以这样的服务和引用都要使用<binding.ws>和服务端点URI进行配置。最后,“cars”引用连到了 TuscanySCATours域中的由CarProvider组件提供的Cars服务,因为这对引用和服务位于同一个域中,所以我们可以使用连线以及缺 省绑定连接它们。“Cars”服务没有对外暴露,也不需要和外部的非SCA程序交互,所以没有必要为其配置可互操作绑定。

接下来,看看TuscanySCAHotels域中由HotelProvider组件周围的连线。除了来自TripBooking组件的“hotels” 引用连到它之外,还有来自HotelBooker(非SCA的酒店预订客户端程序)和TuscanySCAHotels域内的HotelOffers组件 的“hotels”引用。由于“Hotels”服务配置了客户操作的绑定类型——<binding.ws>,所以HotelBooker客户 端软件可以使用任何Web服务程序调用“Hotels”服务。HotelOffers和HotelProvider之间的连接使用SCA连线的原因是这些 组件处于同一域中。这个连线既可以使用缺省绑定也可以使用该服务提供的可互操作binding.ws绑定,在本例中,我们使用binding.ws,目的 是为了说明同一域中的连线也并不一定要使用缺省绑定。

了解图2中所描述的场景在组件配置文件中是如何配置是很有必要的。列表2给出了位于TuscanySCATours域中的组件的定义。

列表2 TuscanySCATours域中组件的组件定义文件

<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
	targetNamespace="http://tuscanyscatours.com/"
	name="toursdomain">
    <component name="TripBooking">
      <implementation.java class="com.tuscanyscatours.TripBooking" />
      <reference name="flights">
	<binding.ws uri="http://flightbookingservice.com:8084/Flights" />
      </reference>
      <reference name="hotels">
    <binding.ws uri="http://tuscanyscahotels.com:8083/Hotels" />
      </reference>
      <reference name="cars" target="CarProvider/Cars" />
    </component>
    <component name="CarProvider">
       <implementation.java class="com.tuscanyscatours.CarProvider" />
    </component>
</composite>

列表3给出了TuscanySCAHotels域中组件的组件定义文件:

列表3 TuscanySCAHotels域的组件定义文件

<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
	targetNamespace="http://tuscanyscahotels.com/"
	name="hotelsdomain">
    <component name="HotelProvider">
      <implementation.java
	class="com.tuscanyscahotels.Hotels" />
      <service name="Hotels">
	<binding.ws uri="http://tuscanyscahotels.com:8083/Hotels" />
      </service>
    </component>
    <component name="HotelOffers">
      <implementation.java class="com.tuscanyscahotels.HotelOffers" />
    <reference name="hotels"
	target="HotelProvider/Hotels" >
	<binding.ws/> 1
      </reference>
    </component>
</composite>
1 此处的引用使用binding.ws进行配置

为HotelOffers的“hotels”引用指定引用绑定是有必要的,如果没有,它就可能被设定成默认的binding.sca绑定,而这样会导致错误,因为它(“hotels”引用)的目标服务的配置中没有提供binding.sca方式的绑定。

图2中的例子展示了引用以及服务的大多数连接方式。不过,对于同一个域中的SCA服务和SCA引用,除了使用SCA连线之外,也可以使用一对匹配的绑定进行连接。很多Tuscany的例子就是这么做的,这样很容易展示如何为客户端和服务端配置匹配的绑定。

我们已经描述了SCA服务和引用连接的若干种选择,这里简要做一个总结。在同一个域中连接引用和服务,你可以:

  • 使用带缺省绑定的SCA连线
  • 使用SCA连线,并为其配置一对匹配的可互操作的绑定
  • 为引用和服务配置匹配的绑定

连接不在同一域中的SCA引用和服务,你可以:

  • 为引用和服务配置匹配的可互操作的绑定。

将引用或服务连接到非SCA程序,你可以:

  • 为应用或服务配置一种可互操作绑定

可互操作绑定使SCA程序能够与非SCA程序交互,也支持不同提供商的SCA程序跨域的交互。而缺省绑定的好处是在互操作不是必须的情况下,提供商可以提供更优质的交互能力。

若了解源代码,示例章节,作者的论坛以及其他资源,请访问http://www.manning.com/laws


这篇文章节选自"Apache Tuscany in Action",它介绍了如何使用绑定进行组件服务连接的配置

若从manning.com购买这本书,InfoQ的读者可以获得25%的折扣,请使用这个折扣码:"infoq25"

查看英文原文:Communication Flexibility Using Bindings

感谢胡键对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家加入到InfoQ中文站用户讨论组中与我们的编辑和其他读者朋友交流。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT