技术开发 频道

详解SOA五种基本架构模式

模式二:主动式服务

    服务的自治性(Autonomous)很重要。自治性能够提高服务之间的松耦合性,并使整体方案产生更好的灵活性。但是自治性服务有什么实际意义呢?有人说,自治性意味着在不同的服务上工作的团队的自治性。这种定义表示,由于各个服务之间只有契约上的关系,因此服务之间几乎没有依赖性。这意味着各团队可以独立工作,专心于自己的服务,而不会互相绊脚。虽然这是一个不错的“功能”,但是同时还有一个更有价值(比如说商业价值)的定义,就是服务是非常自主(self-sufficient )的。下面我们通过一个示例来解释这个定义。

    问题

    有一家报纸订阅代理机构(比如Ebsco或Blackwell),它需要为客户创建一份申请。申请服务的一项内容是产生一份形式上的清单。要得到这样的一份清单,该机构必须同时有给顾客的折扣率和从各出版商处能够得到的折扣,这样才能计算出这份申请是否有利润。图3就是这样一个流程的简单示意图。

    

    在场景示例中,申请服务需要等待另外两个服务的信息。顾客服务是内部服务,与申请服务是同一系统;但出版商的折扣服务却很可能是外部服务——如果出版商的系统没有联机,那么会对我们的申请服务造成什么影响呢?会造成申请服务无法使用。即使我们花费了天文数字的资金来保证申请服务的容错性,但现在的问题是完全无法使用,因为申请服务是与外部的出版商的服务随时耦合的。因此申请服务不具有真正的自治性。

    如何提高服务的独立性以及如何处理暂时性的问题?

    上面所描述的问题表明,仅仅根据请求唤醒的被动式服务是有问题的,因为服务可能无法满足依赖于外部服务的契约条件(或服务等级协议)。

    一个解决办法是让服务对先前的结果进行缓存,但这只能解决部分问题,因为这样做数据就无法得到及时更新,并且时而也会有缓存失效的情况发生,这时仍然需要连接其它服务。这种方法还有另一个问题,那就是如果传入的请求过多,在处理一个请求的时候,其它的请求就会处于“等待”的状态,这样又会产生资源问题,因为而这些“等待”的请求都需要外部服务的输入。

    即使我们解决了前面的缓存问题,我们仍然得处理其它的暂时性事件。暂时性事件包括重复发生,或者与时间相关的一次性事件。比如,生成每月账单或发布股票数据或任何其它重复性的报告都是暂时性事件。一种解决方法是从外部编排服务。这种方法的问题是你得将服务的业务逻辑具体化。但是请记住,封闭的服务层是应用SOA的一个重要原因。因此我们得另寻解决方案。

    解决方案

    要使服务成为主动式服务至少需要一个主动类(Active Class),这个类可以在边界上,或者服务上,或者两者都有。然后让这个主动类处理暂时性问题和管理自治性。

    主动服务模式意味着在服务层上执行“主动类”(见图4)。在Official UML定义中,“主动类”是指“不需要调用方法即可启动自身行为的对象。”这定义对服务也适用。就是说,服务可以有独立的线程来处理循环类事件,比如每月账单或发布状态。主动式服务也可以监控自身的情况,处理超时,甚至可以用来处理请求。

    

    那么,怎么使用主动服务模式来解决我们上面提到的问题呢?就像帕特·森田在《空手道小子》里扮演的宫城先生所说,“最好的防守就是不要在场。”如果你要避免等待另一个服务这种事情发生,那么最好的办法就是不要等待;你可以主动地、周期性地从其它服务获取数据,更新你的缓存。你还能给其它服务减少类似的麻烦,并预先发布自己的变化状态。表面上看起来,缓存数据可能会引起数据重复的问题,但实际上这种情况是不会发生的(详见下面标注)。

    缓存与数据重复问题

    我想有些人,特别是那些学过数据库的人,看到我说从远程服务主动获取缓存数据的时候,肯定会从椅子上蹦起来质疑我远程数据复制的动机,认为我是不是大脑出了什么问题。然而,在我看来,这已经不是相同的数据了。缓存在服务上的数据是服务的数据,可以用来计算、处理甚至根据服务需要进行修改。当然,你也必须明白缓存数据的服务并不是负责控制数据的。

    一个带有计时器的线程基本上足够应付其它暂时性事件了(如果事件少,你可以为每一个事件安排一个定时器;或者定时唤醒,检查哪些事件需要处理并处理它们)。

    使用边界组件的线程处理契约相关的暂时性问题是一个好办法(比如,及时发布状态、超时等),而服务线程则可以处理纯业务类的问题,比如发送每月账单或者处理传入的消息队列。

    现在我们看一下如何使用主动服务模式重装安排图3的情况。简单重复一下,图3是一个申请服务的流程,它需要从外部的发布服务获取外部数据,并同顾客服务一起为顾客生成一份清单(见图5)。现在我们让申请服务主动地定期获取折扣信息并缓存结果,这样当收到产生一份清单的请求时,申请服务就可以即时计算折扣,更快地返回结果,并且(在处理清单请求时)无需依赖外部服务。使用了主动式服务,请求服务便与其它服务分离了。

    

    主动服务模式差不多就是一种理念,没有太多的技术成分。

    技术相关

    这一部分讨论如何使用SOA相关技术实现这个模式;然而,因为这里并没有太多的技术成分,因此我们也只是简单的说明一下。

    主动服务模式的技术理念就是在有特殊功能的服务或边界组件上使用主动线程。从本质上说,主动服务模式取决于线程技术。你可以用任何语言实现这种线程技术。关键在于,你要用这个线程做什么。在上面的段落里我们用了从其它服务缓存数据并处理重复性报告的例子。

    下面的问题就是什么时候应该使用主动服务模式?我们来看一下动机。

    质量属性场景

    这一部分是从需求的角度讨论使用模式的架构效益。大多架构需求是根据使用场景表现的质量属性(可扩展性、灵活性、性能等)来描述的。这些场景也可供其它可以应用模式的情况参考。

    主动服务是一些其它模式(比如前面提到的分离调用和blogjecting watchdog)的先决条件,而这些模式可以帮助处理质量属性问题,比如可靠性与可用性。并且,即使是单独使用主动服务模式也能满足许多质量属性要求。

    通过预先准备的数据,主动式服务可以减少一些潜在的问题。它可以解决期限的问题,因为它能保证服务在期限之前完成任务(比如按时生成每月账单)。另外,主动服务模式还有可用性的优势,因为从其它服务查询并缓存数据意味着减少了服务的可用性对其它服务的依赖性。

    下面的表3列出了一些主动服务模式可以发挥作用的场景。

质量属性(第一层)质量属性(第二层)场景示例
性能延迟正常情况下,评估申请的效益只需要2秒不到的时间
性能期限未满负载的正常情况下,系统可以每少刷新两次以上股票价格
可用性正常运行时间即使断开远程连接,用户仍然可以生成报价单

  

1
相关文章