事务几乎是所有业务交互的必要部分。事务的存在是为了确保适当地记录下特定业务运作的所有部分,如果任何一个单独的部分失败了,那么为了维持数据一致性,事务在整体上应该失败。由于基于 Web 服务的特性,面向服务体系架构的到来为事务管理增加了一层复杂性,服务常常是异步的、无状态的、分布式的,且不透明的。为了让商家从面向服务的方法中获得充分的价值,服务开发人员必须了解事务管理的机制,包括资源募集、业务功能协调、一致性控制,及恢复。
这个两部分的文章讨论了在复杂的面向服务的体系架构中实现事务的特性,以及周围的问题。此处是第一部分,我通过一个事务协调服务(Transaction Coordination Service,TCS)来介绍事务管理,其必须具有组织并控制复杂的业务运作的能力,包括资源募集、业务功能管理、并发控制,及失败恢复。第二部分将介绍事务控制服务(Transaction Control Service)的候选架构。
自动化及业务运作
一百年前,业务运作是劳动密集的。办公室中充满了繁忙,忙碌的职员必需跟踪每个业务交互并且维护一个用于订单、交付,和支付的有组织且一致的记账系统。他们利用人工技术,如双份的会计账目,用以确保在错误实质上影响到业务之前检测并分辨出它们。一个业务“事务”是完整的账目记录,从拿到订单,到客户为产品或服务的最终支付。
现今,软件自动化已经允许以几乎无人的方式来处理业务运作。在没有人工干涉的情况下,接收 Web 订单、评估收费,并交付产品。因此,在维持一个高水平的记账精确性的同时,对商家来说,处理操作已经更加快捷且更加便宜。事实上,事务已经复杂得多,并且在对客户的最终交付时,可能涉及许多公司。例如,设想一个光缆电信服务,客户从电信厂商那里购买卫星频道接入、宽带因特网、蜂窝服务,及因特网游戏预定。该厂商依次与其他厂商签署协议,提供每一种服务并且分享最终付款的一部分。缺少了某种形式的自动化监控,管理这样复杂的业务交互会十分困难(且昂贵)。因而,业务运作现在可能会涉及许多独立的软件系统,以分布式的异步方式进行交互。
面向服务的体系架构(Service-Oriented Architectures,SOA)的引入将此互操作性带到甚至更高层的复杂性。在基于 SOA 的系统中,服务是以松散耦合且独立于平台的方式由一个系统提供给另一个系统的(经常来自多个竞争的公司)。这些服务可以提供任意层次的业务功能,从订单管理,到记账,到存货清单,到执行。通过将一组服务收集到一起,就可能建立一个任意复杂的业务运作,所有的都跨越分布式的网络无缝地交互。当来自一个操作的业务是另一个所需时,错综复杂的部分出现了:例如,存货清单分配需要一个订单号,其顺次生成一个用来计算月记账综述的记账系统所使用的记录。确保此环境下的数据一致性需要事务协调服务(Transaction Coordination Service,TCS)的某种形式的事务管理。TCS 必须有能力组织并控制复杂业务运作,包括资源募集、业务功能管理、一致性控制,及失败恢复。
协调分布式的服务
处理分布式的服务需要非常了解要自动化的业务功能。面向服务的体系架构灵活性(这样服务可以快速地换入换出)的代价是组织并控制业务活动的额外费用。每个服务只提供整个业务事务的一小部分,结果是一个操作进入另一个的处理中(例如订单执行和记账)。要成功地创建复杂、相互依赖的一系列服务,服务协调者(Services Coordinator)(也就是,系统架构师)必须定义每个服务接口,那些服务创建并消费的工作产品,以及处理异常条件的规则。
第一步是定义业务功能,由信息自动化支持的业务过程的一个确定部分。利用 XML 说明业务流和参与者的规范,最近由商业伙伴联盟(包括 IBM、BEA Systems、Microsoft、SAP AG,和 Siebel Systems)发布。该规范称为 Business Process Execution Language for Web Services (BPEL4WS) 1 。该规范允许以独立于平台的方式定义业务功能,类似于 WSDL(Web 服务描述语言(Web Services Description Language))对 Web 服务的声明。当然,实现 BPEL 定义的客户系统必须解析并解释规范的 XML 标签,但是此方法比对服务描述和序列信息硬编码要灵活得多。业务事务由另一组标准来描述 —— WS-Transaction —— 业务功能绑在一起(WS-Coordination)形成要么是工作的独立单元(WS-AtomicTransaction),要么是长期进行操作的集合(WS-BusinessActivity) 2 。
业务功能协作
在 SOA 团队中,业务功能定义用来生成确定的工作产品的分布式服务的集合。例如,lookupOrder(参见图 1)是一个返回详述客户订单信息的确定的数据结构的业务功能。一个更复杂的实例是 finalizeOrder(参见图 2),在其中执行一系列操作来实现订单并更新记账信息。业务工作流中的每个活动由引入的服务、输入参数列表,及输出数据定义。
图 1. 查找订单服务
图 2. 订单服务定案
活动定义(服务和消息)
大多数服务由 WSDL 描述定义,如图 3 所示,其中包含支持的消息类型和服务绑定信息的描述。 3 服务由六个主要要素定义:数据类型、输入或输出 消息、消息传递端口类型、绑定协议、绑定地址端口,及命名的服务。消息数据类型和结构可能遵从一个现有的业务数据传递定义,例如各种各样的 ebXML 实现, 4 或者可能由每个服务提供者定义。绑定协议经常基于 SOAP(简单对象访问协议(Simple Object Access Protocol))或 HTTP(超文本传输协议(Hypertext Transport Protocol)),但是面向服务的体系架构不要求所有服务使用单独的协议,只要求协议是定义了的。连接端口和服务信息也是典型定义了的,尽管如果使用了 UDDI (Universal Description and Discovery and Integration)注册,那么活动定义可能包括用于鉴别来自注册中心的有效服务的信息。
图 3. WSDL 服务模型
功能组织(工作组)
一旦确定了业务功能工作单元及服务,下一个步骤就是将这些活动组织到有意义的工作组中。业务功能工作组是拥有整体统一目的的业务功能集合。 5 例如 OrderManagementGroup,如图 4 所示,将负责引入搜索、检索、创建、修改,和取消客户订单的业务活动。这些服务中的每一个可能由一个有序的服务集执行(一个订单创建业务功能首先检查,看订单还没有存在),包括多种已经传递的消息。活动的组织还提供事务划分的起始点(在下面讨论),在此,特定的业务运作在事务的情况下执行。工作组可能更进一步地链接到链式操作中,在此,要么执行串行的操作(例如订单创建、处理,及实行),要么执行并行的操作(例如存货分配、账单生成,及账目更新)。
图 4. 服务组(服务划分)
协调点(事务划分)
一旦确定了业务活动,并且定义并将服务集分了组,那么下一个步骤就是指示 事务划分点。不是所有的业务运作都需要事务管理,只有那些包含多个操作,需要以所有操作必须成功完成的方式协调的。在图 5 中所示的实例中,LookupCustomer 和 CreateCustomerRecord 没有包装到事务中,但 FinalizeCustomerOrder 参与了一个 Create Order Transaction 划分了的服务集。在此实例中,FinalizeCustomerOrder 服务使用 Transaction Management Service(TCS)来控制其他四个服务的顺序操作,并提供对 TCS 进行的每个操作所必要的消息(显示为 FinalizeCustomerRequest 的附件)。
事务协调图用来显示确定的事务的构成、处理顺序(顺序的 vs. 并行的),及嵌套的事务。在图 5 中的实例中,GenerateShippingRequest 是 Assign Inventory Item 服务所创建的嵌套事务。嵌套事务出现的原因可能有许多,例如,如果打算将服务独立使用,或作为更大事务环境的一部分。注意到嵌套的事务可以使用同一个 TCS,确保如果嵌套事务失败了,那么父事务也将失败。
当事务处理完结时,TCS 轮询事务的所有参与者,决定该事务是否应该提交。在一个两阶段提交协议中,TCS 首先轮询参与者,看是否它们准备好了,然后依次向每个参与者发布提交。如果事务参与者没有准备好,那么所有其他的参与者得到回滚命令。在参与的服务察觉不到事务(举例来说,无状态的)的情况下,TCS 将调用补偿操作(也就是,“取消”)。
图 5. 提交订单事务划分
处理控制(串行的或并行的)
如上面所提到的,事务控制可能是串行的、并行的,或两者的组合。定义为串行的事务必须按照特定顺序发生,且典型的是在来自一个操作的完成的事务环境信息是另一个的必需输入时(举例来说,当订单号记录在存货分配或记账记录参考上的时候)需要串行事务。另一方面,并行操作是互相独立的,因此可以同时执行。例如,由空中旅行、饭店逗留,及汽车租赁所组成的旅行计划可能并行执行,因为一个操作的结果不是完成另一个所必要的,如图 6 所示。当事务的一个部分是串行的,而其他部分是并行的时,会出现组合的处理。此类型的事务的一个实例是光缆产品的订单,在此第三方供应商独立供应。
图 6. 并行事务处理
处理环境(内部映射、外部映射)
最后,TCS 要求在事务开始之前分配事务环境信息映射。这意味着服务协调者(Service Coordinator)必须知道每个服务所需的信息,并确保每个服务调用都配备必要的事务环境。在之前图 5 中所示的串行实例中,CreateOrder 服务生成一个其他两个服务所需的接口上的一部分,OrderID。服务协调者该提供内部映射和外部映射信息来考虑要添加到随后的服务调用中的环境信息。如图 7 所示,外部映射将显示 CreateOrder 服务创建的 OrderID 映射到 Billing 和 Inventory 操作的输入内部映射。此映射让 TCS 将环境信息传播到事务的所有单元。
图 7. 事务环境映射
实现 TCS
面向服务的体系架构包含一组服务,每个服务需要特定系统资源来执行其工作。一个预定服务可能需要有权安排信息,而一个发货服务可能需要调用上述的预定服务来安排一个特定的发送给客户的存货条目。服务可以声明其功能、向注册中心提交此信息,并提供安全通信。TCS 可以在事务过程中利用此信息,定位正确的服务集、发现其功能,并依次向每个服务传递环境信息。
资源发现和注册(UDDI)
TCS 可以通过两种方式了解到哪个服务参与到事务中:每种都是计划性的,通过服务协调者在给 TCS 的注册消息中指定服务细节,或者通过在注册中心中进行查询。UDDI (Universal Description Discovery and Integration) 注册规范设计让服务实现者连同集成信息(例如安全性、事务意识、恢复等)一起注册服务。
资源功能声明(策略)
事务中涉及的服务需要对 TCS 声明其功能。 6 特别地,一个服务必须声明其处理事务的能力,或者如果它不能(举例来说,CreateOrder 服务必须拥有 CancelOrder 服务),就要提供补偿服务。此外,功能声明说明了安全策略,以便多种服务可以参与安全事务通信。
安全(验证或授权)
服务负责实现安全性。安全策略 7 定义用于在 TCS 和服务之间创建一个安全访问通道的声明。策略定义了安全协议及 TCS 和服务之间的安全互通性所需的信任通道。
分布式环境中的并发控制
除了服务所需的其他资源管理以外,处理并发的能力是纠正事务管理的关键。每个参与 TCS 中事务的服务必须能够确保事务过程中执行的变更不被其他事务覆盖。 8 例如,一个事务开始时,用新购买的产品更新客户订单。在该订单处理时,另一个事务开始取消某些变更。如果这些事务冲突了,那么要取消的产品将被替代,其他将要被供应的可能取消 —— 一点也不管客户要的内容!
因此,当服务参与事务时必须实现某种形式的数据加锁或发布策略。这与关系数据库中为了维护多个并发事务所使用的操作类似。这些策略包括检查每个操作的时间戳及为进度确定的正确顺序,以及什么时候或如何锁定记录(举例来说,乐观的 vs 悲观的加锁)。最后,当资源出现死锁(一个服务持有另一个服务需要的锁,反之亦然)时,服务将需要实现某种形式的死锁消除。 9
恢复及重试
TCS 的最后一个需求是在事务失败时实现重试及恢复。要考虑两种事务失败:第一种是所有服务都能够参与事务时,而第二种是包括一个或多个不能参与事务的服务。在第一种情况下,TCS 可以使用两阶段提交协议 10 来管理事务步骤。在第二种中,服务必须拥有补偿服务来考虑第一种动作的取消。第一种情况的一个典型的例子是所有的服务访问标准的关系数据库(其实现了两阶段提交),或者由 OpenGroup X/Open transaction 语义定义。 11 第二种(不幸地是更加通用)的一个实例是在服务完成处理时提交操作 —— 例如对饭店预定利用饭店的 Web 服务接口。
TCS 也可以实现重试语义。在这种情况下,TCS 将长期执行的事务存储到持久存储设备上,并且试图在较后的时间完成事务。例如,如果在购买旅行计划的地方建立事务,那么航空预定部分也许在饭店、汽车、高尔夫、正餐、巡航等部分之前完成。TCS 可能在舍弃初始的航空预定之前推选重试任一或所有余下的事务单元。这是“保险的”事务的一个实例,TCS 将试图通过多次重复提交失败单元来完成事务。
在面向服务的体系架构中实现事务的挑战
存在许多在面向服务的体系架构中实现事务管理才有的挑战。首要的是服务自身的特性:服务是松散耦合的,所以它们试图成为无状态、异步、分布式,且不透明的。无状态的服务意识不到事务状态,因此如果事务失败时,不能请求它们“回滚”一组变更。如果按照 Web 服务来实现一个服务,那么当前的协议利用 Internet 的异步特性,这意味着服务不能够及时地对请求进行响应。对于并行操作,这不是一个因素,但考虑当事务是串行的且来自一个服务调用的信息可能是其他服务调用所需时。
以 Web 服务形式实现的服务是可以在任何位置访问到的,因此它们是分布式的定义的,对潜在性、可靠性,和安全性的关注的引入影响了事务管理。
最后,服务只是由对 TCS 的确定接口可知的,在服务处理的内部没有详细信息。这导致“黑盒”使用模式,一个服务在不知道客户端知识的情况下利用其他服务,因而传播带有二次影响的变更。对于事务,这可能意味着,作为事务一部分的服务可能调用了同是该事务一部分的另一个服务。这可能导致重要的并发问题,因为第一个调用可能更改了第二个所需的数据,导致一个很难跟踪的问题。
假设存在所有这些挑战,创建一个可靠的 TCS 对任何实现面向服务的体系架构的人来说都是困难的任务。TCS 必须能够管理带有嵌套、并发、安全、进度,及本文中所讨论的所有其他问题的任意复杂的事务。因此一个可怜的服务架构师能做什么?本文的第二部分将通过介绍一个事务控制服务的候选架构来解决这些问题。
文章来源于领测软件测试网 https://www.ltesting.net/
版权所有(C) 2003-2010 TestAge(领测软件测试网)|领测国际科技(北京)有限公司|软件测试工程师培训网 All Rights Reserved
北京市海淀区中关村南大街9号北京理工科技大厦1402室 京ICP备10010545号-5
技术支持和业务联系:info@testage.com.cn 电话:010-51297073