zoukankan      html  css  js  c++  java
  • 《面向模式的软件体系结构3资源管理模式》读书笔记(7) Coordinator模式

    3.3 Coordinator模式

          Coordinator(协调者)模式描述了如何通过协调涉及多个参与者(每个参与者都包含资源、资源使用者和资源提供者)的任务的完成来维护系统的一致性。这个模式提出了一个解决方案,使得在涉及多个参与者的任务中,或者所有参与者的任务都完成,或者一项任务都没有完成。这确保了系统总是处于一致的状态。

    1.问题

          很多系统都会执行涉及不止一个参与者的任务。一个参与者是一个主动实体,既包含资源使用者,也包含资源提供者。此外,在某些情况下,资源(比如服务)可以是主动的,所以会直接参与任务。参与者可能位于同一个进程中,也有可能跨越了多个进程、多个节点,每个参与者都会顺序执行任务的一部分。为了让任务获得整件的成功,每个参与者执行的工作都必须成功。如果任务成功执行,那么改变就应该让系统保持在一致的状态。但是,考虑一下如果一个参与者执行的工作失败了,会发生什么。如果这项工作位于任务执行序列的较后面的阶段,那么已经有很多参与者完成了其工作。这些参与者的工作会给系统造成改变。但是,失败的参与者无法对系统造成必要的改变,结果就是,系统的改变是不一致的。这可能会导致不稳定甚至出错的系统。在这样的系统中,部分失败甚至比全局失败更糟糕。

          一个可能的解决方案是在参与者之间引入点对点的通信。每个参与者都把自己的工作结果传达给别的参与者,并采取必要的步骤以保证系统状态一致。但是,这样的解决方案要求所有参与者都关注任务涉及的其他所有参与者,这是不现实的。此外,这样的解决方案对参与者数量的可伸缩性也很糟糕。为了解决这些问题,需关注以下几点:

          1)一致性(Consistency)。一项任务应该要么为系统建立新的合法的状态,要么(若发生了错误)把所有的数据都恢复到任务开始前的状态。

          2)原子性(Atomicity)。在涉及两个或多个参与者的任务中,或者所有参与者的工作都完成,或者所有工作都没有完成(虽然参与者是彼此独立的)。

          3)位置透明性(Location transparency)。解决方案应当可以用于分布式系统,虽然分布式系统比整体式系统更有可能遭遇局部失败。

          4)可伸缩性(Scalability)。解决方案应当对参与者的数目具有可伸缩性,而不会显著地降低性能。

          5)透明性(Transparency)。解决方案对系统使用者应该是透明的,并且应该尽量减少对代码改动的要求。

    2.解决方案

          引入协调者,负责所有参与者执行和完成任务。所有参与者执行的工作都分成两个阶段:准备(prepare)和提交(commit)。

          在第一阶段,协调者要求每个参与者准备完成的工作。每个参与者必须用这个阶段来检查一致性并判断执行结果是否会失败。如果某个参与者的准备阶段没有返回成功,那么协调者就停止任务的执行顺序。协调者会要求所有成功完成准备阶段的参与者都中止并恢复任务开始前的状态。因为参与者都还没有做出永久性的改变,所以系统状态保持了一致。

          如果所有的参与者都成功地完成了准备阶段,那么协调者就发起每个参与者的提交阶段。参与者会在这个阶段做实际的工作。因为每个参与者都在准备阶段表明工作会成功,所以提交阶段会成功,整个任务被成功执行。

    3.结构

          任务(Task)是一个单元的工作,它涉及多个参与者。

          参与者(Participant)是一个主动实体,它会完成任务的一部分工作。参与者可以包含资源使用者,资源提供者和资源。

          协调者(Coordinator)是负责协调任务整体完成的实体。

          客户(Client)是任务的发起者。客户指导协调者执行任务。

           

            

    4.实现

    1)识别参与者。任何参与者,只要其工作需要被协调,那么就必须在一开始就识别出来。在资源管理的背景中,参与者可能是资源使用者,资源提供者或者资源本身。资源使用者可以成为参与者,如果它主动地试图获取、使用以及释放多个资源,从而需要协调的话;资源提供者也可以是参与者,如果它试图向资源使用者提供一个或多个资源的时候需要协调;资源(比如服务)也可以是参与者,如果它是主动的,并且因而能够直接参与任务。

    2)定义协调接口。应该定义一个将被执行任务的一部分工作的参与者实现的协调接口。

    public interface Coordination{

        public boolean prepare();

        public void abort();

        public void commit();

    }

        协调者使用prepare()方法来对每个参与者发起准备阶段。每个参与者都会使用这个阶段来检查一致性,并判断执行是否会导致失败。返回值true意味着准备阶段成功,因此提交阶段也会成功。返回值false意味着准备阶段失败,因此参与者将无法成功执行提交阶段。

        如果在准备阶段任一参与者返回了false,那么协调者将会中止任务的执行。它会调用每个已经从准备阶段成功返回的参与者的abort()方法。这就向参与者表明,任务被中止,它们需要执行所有必要的清除操作。

    3)定义协调者接口。协调者接口应该为客户提供了开始或者结束任务的方法。此外,它还应该允许任务的参与者注册。在参与者可以注册它们之前,它们必须可以发现协调者。为了做到这一点,参与者可以使用Lookup模式。

    public interface Coordinator {

        public void beginTask();

        public void register(Coordination participant);

        public boolean commitTask();
    }

        客户使用beginTask()方法来定义任务的开始。此时,协调者不做任何事情。当任务一开始,任务的参与者就用register()方法向协调者注册。一旦所有的参与者都注册了,客户就执行协调者的commitTask()方法。这时协调者而言意味着两件事件——首先,所有的任务参与者都已经注册;其次,协调者可以开始协调参与者执行任务了。现在协调者使用协调接口定义的两个阶段的提交协议来确保参与者完成任务。

    4)处理错误条件。使用协调者允许参与者表明它们负责的工作是否成功。如果任一参与者表明它的工作没有成功,那么协调者就可以中止任务,而不会导致系统状态的任何持久不一致性。如果所有的参与者都表明准备阶段成功,那么协调者就接着对所有参与者执行提交阶段。但是,还是会有这样的可能性:一个或者多个参与者在提交阶段失败,虽然它们的准备阶段成功完成了。这可能是由参与者无法控制的因素导致的,比如连接被断开了。为了处理这样的错误条件,参与者可以在执行它们负责的任务部分之前可选地维持状态信息。如果一个参与者提交失败,那么协调者可以对剩下的提交成功的参与者调用rollback()方法。这会给参与者一次机会,让它们恢复在执行任务之前的状态,不过,这样的功能要求维护状态信息,可能代价高昂。

    5.结论

    优点:

    1)原子性(Atomicity)。Coordinator模式确保了在涉及两个或者多个参与者的任务中,或者所有参与者的工作都完成,或者所有工作都没有完成。准备阶段确保了所有参与者都能够完成工作。如果任一参与者在准备阶段返回失败,那么任务就会被执行,这确保了没有任何参与者完成工作。

    2)一致性(Consistency)。Coordinator模式确保了系统状态保持一致。如果一项任务被成功执行,那么就为系统建立了新的合法的状态。另一方面,如果发生了任何失败,那么Coordinator模式确保所有的数据都回复到任务开始之前的状态。因为每个任务都是原子的,要么所有参与者都完成它们的工作,要么没有参与者完成任何工作。在这两种情况下,结果都是系统处于一致的状态。

    3)可伸缩性(Scalability)。解决方案对于参与者的数据具有可伸缩性。增加参与者的数目不会影响任务的执行。随着参与者数据的增加,其中一个参与者失败的可能性也增加了。但是,使用这个模式,失败会在准备阶段被检测到,从而确保了系统处于一致的状态。

    4)透明性(Transparency)。使用Coordinator模式对于用户是透明的,因为任务的两步提交式执行对于用户是不可见的。

    缺点:

    1)额外开销(Overhead)。Coordinator模式要求每项任务都分割成两个阶段,这会导致涉及所有参与者的执行序列被重复两次。如果参与者是分布的,那么这就意味着两倍的远程调用数据,这还可能会导致失去透明性。

    2)额外的职责(Additional responsibility)。Coordinator模式为参与者增加了额外的职责,它们还需要向协调者注册。如果参与者是分布的,那么注册过程会导致参与者执行远程调用。 

  • 相关阅读:
    记-码农的“启蒙”之《程序设计语言-实践之路》和《面向对象分析和设计》两书
    记-阅读以及书籍推荐(2014年9月7日更新)
    初探领域驱动设计(1)为复杂业务而生
    异步编程 In .NET
    Windows平台分布式架构实践
    Windows平台分布式架构实践
    一不小心写了个WEB服务器
    MVC5
    从Membership 到 .NET4.5 之 ASP.NET Identity
    bootstrap + requireJS+ director+ knockout + web API = 一个时髦的单页程序
  • 原文地址:https://www.cnblogs.com/pennant/p/2725391.html
Copyright © 2011-2022 走看看