代码改变世界

WCF 面向服务的4个原则

2011-07-26 15:07  田志良  阅读(...)  评论(... 编辑 收藏

边界清晰

  在面向服务里,服务可以与每个其它的服务通过消息交互。换句话说,服务可以穿越边界发送消息给其它服务。服务可以发送和接收消息,并且能被发送和接受的消息形状定义了服务的边界。这些边界被良好地定义,清晰地表示,并且是唯一的服务功能访问点。更实际点,如果服务1要和服务2交互,服务1必须发送消息给服务2.相反,一个面向对象或者面向组件的世界里,要求服务1应该创建一个服务2的实例(或者一个服务2的代理)。这个例子里,这些服务间的边界变得模糊了,因为服务1为了所有的目的,被服务2所控制。

  如果服务1发送消息给服务2,服务2的位置有问题吗?答案是否,只要服务1允许发送消息给服务2.有人会猜测发送消息穿过边界会带来成本。当构建服务的时候这个成本应该被考虑进来。尤其是,我们的服务应该尽可能少的穿越边界。高效服务的对面就是“罗嗦”(这里比喻穿越服务边界反复发送不必要的消息,从而带来不必要的成文消耗)。

服务自治(一定程度)

  我的观点是,面向服务的系统应该努力成为有几分自治的服务,因为纯自治是不可能的。真正的服务自治意味着服务除了自己不依赖任何东西。在现实世界里,这种类型的实体是不存在的,我怀疑我们在分布式计算的世界里将会看到许多纯自治的服务。一个真正的服务自治服务是动态建立通道、动态地协商安全策略、动态地询问消息Schema、动态地与其它服务交换消息。一个纯自治的服务意味着一个迟绑定的架构。我们已经看到这种系统,无论是在IUnknown接口还是在反射的滥用里。底线就是开发者和架构师一次又一次的证明这些类型的架构不起作用(尽管书上说的很棒)。我必须修改这些评论,承认面向服务领域里的舞步精彩的有些令人眼花缭乱。仅仅5年以前,面向服务的应用系统非常少见,现在却很平常。这个动力也许会带我们到通往纯自治服务的路上,但是现在我认为没有必要过于强调太多自治的问题。

  实践上,自治意味着什么?从实际角度出发,它意味着服务是可以控制生命周期的、控制可用性和控制另外服务的边界。这个行为的反面例子可以用SQL 2000数据库和代理说明,两个服务都是作为Windows服务里托管的,但是代理服务有一个内置的数据库服务依赖。停止数据库服务意味着代理服务也会停止。这个服务间的紧耦合意味着它们不可能分开,或者独立的版本控制。紧耦合降低了买个服务的灵活性和在企业里的应用。

契约共享

  因为面向服务关注在参与者之间传递的消息上,必须有一个方式可以描述这些消息和成功的消息交换需要什么。广义上,这些描述被称作契约(contract)。契约不是新的编程概念。在Windows平台上,契约产生在COM和DCOM里。一个COM组件只能被发布和共享的契约访问。实际上,契约就是接口(Interface),用接口描述语言(IDL)来表示。这个契约使得调用者不知道实现细节。只要契约不被破坏,调用者可以包容COM组件的软件升级和更新。

  面向服务的系统概念上扩展了COM IDL契约。面向服务的系统用更广泛理解的语言XSD和WSDL来表述契约。更明确点,Schema被用来描述消息结构,WSDL用来描述消息终结点。总之,这些基于XML的契约表示发送和接受的消息结构、终结点地址、网络协议、安全需求等等。XML的自然属性允许发送者和最终接受者与COM相比可以更容易地运行于任何平台。在这些东里里,发送者必须知道接受者的消息结构和格式,这些契约都会给出定义。本质上,一个消息发送者需要依赖于契约而不是服务本身。

基于策略的兼容性

  服务必须能够描述其它服务与之交互的底层环境。例如,一些服务需要需要初始发送者拥有一个有效的AD账号(Active Directory)或者X509证书。这种情况下,服务必须在一个基于XML的策略里表达这些需求。WS-Policy是表达这些需求的标准语法。在被狂热追求的面向服务的世界里,消息发送者需要先询问元数据而不是发送消息,更进一步解耦服务发送者和消息接收者。与前面提到的原因一样,服务策略更可能在设计时询问而不是运行时。