扫一扫
关注微信公众号

使用日志作为应用程序的架构
2008-07-16   IBM中国

日志对许多应用程序来说是都是一个重要的组成部分,至少存在两种类型的日志: 一般信息的关键业务的

一般信息日志主要用来跟踪应用程序的步骤和操作。根据日志信息的用途,它对应用程序的操作有着不同的影响。例如,如果日志记录只是用来进行统计分析,少数几次失败的日志操作将是可以接受的。然而,如果日志是用来审计,那么遗失日志记录将是不可接受的,这就要用到第二种类型的日志:关键业务日志。

在这种情形下,根据业务的相关程度,日志的输出将影响到系统的其它部分,换句话说,其它应用程序将读取关键业务日志并应用到它们的商业逻辑中。这种类型的日志将像其它的一些业务操作一样被谨慎处理。这类日志的一个例子就是金融系统的日志,那些记录财务事务信息的日志可用来进行兴趣统计、税费计算或仅仅是用来满足法律要求,如可跟踪性。

不幸的是,在目前系统在,一些重要的日志消息,(可能是一般信息日志或关键业务日志),很少被认真处理。原因在与日志操作经常被当作一种辅助操作,日志资源被当作一种只写的设备,只满足快速和廉价即可。

基于日志的自身内在特性,Web 服务是实现日志的很好的选择。因为对业务关键日志敏感的企业同样会对一个企业范围内所有应用程序都能够使用的日志服务感兴趣,并且Web服务还提供了日志记录及其生命周期的集中管理能力。

在本文中,我们将提出一种企业范围的日志 Web 服务架构,它重点解决分布式系统 2 个关键设计方面: 可靠性和容错性事务语义支持的日志

日志的容错性和可靠性
在本节我们将基于 WS-Reliability 标准讨论与日志有关的 Web 服务可靠性问题,并提出一个可靠的日志 Web 服务架构方案。

可靠日志的需求
在讨论技术细节之前,我们首先定义可靠性以及日志 Web 服务需要实现的可靠性需求

可靠性定义

从一个用户的角度出发,可靠性经常是一种需求,下面两段引文对什么是可靠性给出了很好的定义:

  • 根据文献 分布式系统-概念和设计(请参阅 参考资料),一个计算机系统的可靠性是对系统的行为偏离它最初的设计行为(即根据正确行为的定义)的可能性大小的度量,它包括在没有任何个别的错误操作的前提下发生的系统中止。可通过设计系统来发现系统偏离(或错误)并从中恢复来提高系统可靠性。
  • 可靠性的第二个定义源于文献 分布式系统-原理和示例(请参阅 参考资料) ,它指系统在不发生故障的前提下连续运行。一个高可靠系统是指系统在无故障前提下一个相当长的时间周期内可以最大可能的持续不间断工作。.

这两个定义从根本上说明,你希望建立的日志 Web 服务是在一个相对较长的时间范围内可以不间断工作,且具有发现故障并从中恢复的能力。

日志需求

记住上面的定义,则不难确定一个可靠日志 Web 服务的可靠性需求。下面的列表描述了一个可靠日志 Web 服务所必须实现的需求:

  • 实现可靠的消息传递:未来的设计技术方案必须保证提交到日志 Web 服务日志消息能够传递到服务器端且被处理。
  • 除去重复消息:日志 Web 服务除了必须保证消息被提交外,还要确保即使一条消息被提交多次,在服务器端也只处理一次。
  • 确保消息次序:协议和设计技术方案必须保证提交到 Web 服务的日志消息按照它们的发送时的次序在服务器端处理。
  • 日志客户端和 Web 服务容错性:日志客户端和 Web 服务需要能够发现错误并能够从错误中恢复。

这意味着,要实现一个可靠日志 Web 服务,未来的技术方案必须保证消息传递到服务器端并按照正确的顺序处理一次(且仅处理一次)。另外,方案必须保证提交的日志信息必须是可持续化的,即使服务器或客户端崩溃等特殊时刻。

高层架构
在详细讨论之前,我们还必须明确几个定义。在本节,我们为日志 Web 服务提出了高层架构,研究架构体系内的组件,并定义整节中使用的通用术语。

交互

图 1 显示了组成日志方案的高层组件,并定义了日志客户端与 Web 服务进行交互的两个场景。

图 1: 日志场景
日志场景

图 1的上半部分显示了最基本的场景。 这里,日志客户端与日志 Web 服务直接进行交互。

图 1 下半部分显示如下场景: 日志客户端并不直接与日志 Web 服务进行交互,日志信息被传递到一系列称为跳转的中间服务。不管是日志客户端的直接通信组件还是日志 Web 服务来作为跳转,都需要保持透明。

本文将不对跳转进行单独讨论,但从架构的观点来看,如果与日志客户端交互,那么它就像一个日志 Web 服务,如果与日志 Web 服务交互,那么就是一个日志客户端。

组件

在上一节我们研究了主要组件-日志客户端和日志 Web 服务。在本节我们将从架构的角度对日志 Web 服务进行详细研究。

图 2: 基本日志服务架构
基本日志服务架构

图 2 中的高层视图并没有给出太多的技术细节,只是用来说明组成日志 Web 服务的 2 个主要组件。

简单地,日志 Web 服务从总体上可以分为 2 部分:

  • 日志客户端:组件封装了一个可靠日志客户端,应用程序通过提供的 API 可以使用它。组件可以从应用程序中接收日志信息并通过可靠的方式提交到日志服务器。在本文中这一组件通常被称作 客户端日志客户端.
  • 日志服务器:此组件是应用程序的核心部分,它为日志客户端提供了一个进行可靠日志的 Web 服务。日志服务器接收日志信息并采用可靠的方式进行处理,在本文中这一组件通常被称作 服务器日志服务器.

应用程序是 图 2 中的第 3 个组件. 应用程序并不属于日志 Web 服务,由于它使用 Web 服务,因此它在本文上下文中也很重要。

在整篇文章中,这一组件被称为 商业应用程序.

WS-Reliability 标准
作为讨论的基础,我们对 WS-Reliability(请参阅 参考资料)进行概述,并讨论了它的关键元素和机制。 然而,你会发现, WS-Reliability 标准很好地覆盖了协议层上关于可靠性的问题,但并没有涉及到应用层上的可靠性问题,而这些问题正是本文中着重讨论的,以此来弥补协议层与应用层之间的差距。

WS-Reliability 标准的目标
WS-Reliability 标准的目的在于通过定义客户机服务器之间的通信机制,使得 Web 服务满足如下要求:

  • 提供可靠消息传递( 至少一次语义)
  • 除去重复消息( 至多一次语义)
  • 确保消息次序

WS-Reliability 定义的消息关键元素
WS-Reliability 提出了一种基于消息/确认(message/acknowledgment)模型的可靠性解决方案。这意味着每个消息发送者在发送一条消息后都会等待从服务器返回的一条回应消息-确认。

图 3: WS-Reliability 中的日志消息/确认模型
 WS-Reliability  中的日志消息/确认模型

图 3显示了 WS-Reliability 规范中定义的一个消息场景。这里我们使用消息来取代 日志消息。 WS-Reliability 并不是特定日志消息而是适用于通用消息。但从我们的角度重发,我们只考虑日志应用程序。 #p#副标题#e#

一个日志客户端发送一条日志消息给 Web 服务, Web 服务接收到日志消息后,如果有必要的话除去重复的消息,然后对消息进行处理。一旦处理完毕,它将发送一条确认消息给客户端。

由于这篇文章不是用来专门讨论 WS-Reliability 标准,因此,我们不会讨论整个标准,但将会讨论其中的几个关键元素,特别是与可靠日志服务相关的特性元素。

首先,日志请求消息中包含的关键元素如下所示:

  • Message-ID: 这是在消息发送前被指派的序号。通过这种方式, Web 服务在一条消息被重复提交多次的情况下能够避免重复处理,同时还能够保证消息之间正确的次序。
  • Ack-Requested: 这一元素允许客户端来决定对于发送的消息是否需要确认。对于一个可靠的日志 Web 服务,这一属性标志必须为真。
  • Duplicate-Elimination: 根据这一属性,客户端可以决定服务器是否需要进行去除重复消息的处理。对于一个可靠的日志 Web 服务,这一属性标志必须为真。

确认消息中唯一一个重要的元素是字段 Ref-To-Message-ID 。 这一字段包含了确认消息所回应的日志消息的序号(Message-ID)。

从上面列出的几个元素你可以看到, WS-Reliability 规范覆盖了 “可靠日志的需求”一节中提出的 3 个需求。上述特性提供了可靠日志在协议层的解决方案,但并没有提供应用层的解决方案,如可靠日志第 4 个需求,但它为解决应用层的问题提供了基础。

在下面一节,我们列出了在应用层可能发生的错误,并提出了一个可以解决这些错误问题的解决方案。

日志在应用层的可靠性问题
为举出应用层的可靠性问题,让我们重温回顾一下 图 3中的日志场景:

  1. 客户端对服务器发出日志请求
  2. 服务器接受到日志请求
  3. 服务器序列化日志请求
  4. 服务器发送确认给客户端
  5. 客户端接收到服务器发送的请求信息

上面的流程整体上提供了一种可靠消息传递机制:一个客户端发送一条日志请求,服务器在完成消息存储之后发送一条确认信息。但上述流程并不是意外安全的,因为在下述情形下上述流程将被打破,随之而来的便是没有确认消息返回到客户端:

  • 如果客户机无法定位服务器怎么办?
  • 如果请求消息丢失怎么办?
  • 在存储或尚未存储日志信息的情形下,服务器崩溃怎么办?
  • 如果确认消息丢失怎么办?
  • 如果客户机崩溃怎么办?

在上述每一种情况下,你都必须保证日志消息被存储且客户端接收到确认消息。在某些条件下要确保这一点可能会很困难。下面我们将对上述情况进行详细讨论

客户机无法定位服务器
如果客户端不能够定位服务器,则将导致日志服务失败。但这个问题客户端可以进行控制,因此,服务器端或协议层不需要特别的机制来处理这一状况。

如上所述,日志信息在被日志客户端提交到服务器端后绝不能够丢失。如果客户端不能够定位服务器,将出现下面两种情形:

  1. 服务器暂时无法连接。
  2. 服务器永久无法连接,或至少看起来如此。

设计一个基本的假设是:服务器的连接状况对于业务应用程序尽可能透明。

在第一种情形下,日志客户端能够针对服务器无效的状况对业务应用程序保持透明。日志客户端将从业务应用程序接收的日志信息重复(使用同一个序号)发送,如果客户端遇到的是服务器的瞬间故障,一旦服务器功能回复,它将马上处理日志信息。

如果在 n 次尝试后仍无法连接服务器,客户端有理由认为服务器永久无法连接,因此需要将这一状况报告给调用日志客户端的业务应用程序。

请求信息丢失
在某些情形下客户端和服务器之间的消息可能会丢失,如传输层上的包或当一个消息在一个跳转链上进行传输时,其中的一个跳转突然崩溃。

做为一个设计特色,消息确认使得客户端能够确定请求信息是否丢失。如果请求信息在发送到服务器的途中丢失,或者服务器在处理请求信息之前崩溃,那么客户端不会接收到请求消息。

为了避免客户端与服务器间的临时连接超时的影响,客户端将重复发送 n 次消息,如果这种连接超时依旧存在,客户端在重复发送了 n 次后将停止重复发送日志信息并向调用客户端的业务应用程序报告这一错误。

服务器故障
如果服务器发生故障,客户端将从服务器得不到确认信息,将有可能发生两种情形:

  • 服务器在接收到信息之后但在存储信息之前崩溃。
  • 服务器在存储信息之后但在发送响应信息之前崩溃。

在上述两种情形下,你都希望客户端能够重新发送日志信息给服务器而且这些信息不会被服务器多次处理。就像你希望任何服务器上的故障对客户端都是透明的一样。

在第一种情况下,由于消息尚未被处理,客户端只需要简单的提交信息,而服务器端不需要采取任何特殊行为。

下面考虑第二种情形,你会注意到当第一次发送的消息被再次提交,则日志消息将会被处理 2 次,因为这条日志信息已经被记录了。因此,客户端必须能够保证在服务器不会第二次处理消息的前提下重复提交信息。为解决这个问题,服务器必须包含一个状态变量来标识提交的消息已经被处理但确认消息尚未发出这一状态。

在协议层,架构方案为解决这一问题提出消息序号,或在 WS-Reliability 被称为的 Message-ID ,根据消息序号和服务器端的存储日志,服务器能够鉴别处重复提交的日志消息。

根据这个架构,你可以看出日志 Web 服务根据需要进行工作,不会将已经提交的信息进行重复处理。一个日志客户端提交信息给服务器。服务器接收到信息,然后检查存储日志来判断这条信息是否在之前已被处理。如果尚未被处理,换句话说,存储日志中不存在对应的条目,服务器将处理日志信息,如果处理成功,在返回确认消息之前,将在存储日志中创建一个条目。如果消息已经被处理,换句话说,存储日志中存在对应的条目,则服务器将不会处理消息而是立即返回确认信息。

需要注意是,要使架构能够正确工作,包含存储日志的文件系统绝对不能够溢出。

确认消息丢失
像日志消息一样,确认消息由于某些原因也会丢失,同样,客户端无法确切知道哪里发生了错误。然而,像上面提到的,通过使得服务器具有容错性,客户端可以简单的重新发送日志消息来等待确认信息的到达。

为将暂时错误与永久错误区分开,客户端可以采用与上面所述的同样的策略。客户端发送 n 次日志信息。如果在发送 n 次信息后仍旧没有接收到确认消息,客户端有理由认为系统遇到永久性故障,它可将这一故障信息返回给调用者或业务应用程序。

客户端崩溃
对于可靠日志来说,日志客户端将是一个业务应用程序的主要组成部分。业务应用程序的许多操作或任意操作都伴随着日志操作。由于日志客户端的同步特性,如果日志应用程序运行失败则业务应用程序同样也会失败。

提出的架构

组件
根据上节中讨论的内容,我们提出如 图 4 所示的架构.

图 4: 日志客户端和服务器架构
日志客户端和服务器架构

客户端提供了一组 API,业务应用程序通过它能够访问日志客户端。控制器包含日志客户端的业务逻辑。在客户端的底层,你将发现客户端使用的实现了传输协议的通信 API。

服务器包含一组通信 API 用来与客户端进行通信,一个存储日志用来保存状态,还有一个日志消息仓库。为实现上一节所讲的业务规则,通过一个控制器组件将服务器内的所有组件紧紧联系在一起。

日志需求与体系结构的关系
在对本节进行总结之前,让我们看一下体系架构是如何满足前面所述的日志需求的

  • 实现可靠的消息传递:请求/确认协议使得客户端能够判断消息是否传递到客户端。
  • 除去重复消息:由于服务器包含一个状态变量,因此重复的日志消息能够被除去。
  • 确保消息次序:由于日志客户端的同步特性,如果没有接收到前一条日志消息的确认信息,日志客户端将不会发送新的日志消息,日志消息将按照正确的顺序依次处理。

消息编号
在所提出的架构中还有一个重要但尚未进行讨论的设计特征,那就是消息编号。对于所提出的架构来讲,实现消息编号的一个最佳方法便是将 HTTP 会话 ID 与发送消息的时间戳进行组合。时间戳的保证了不同的日志消息具有唯一的序号。根据 HTTP 会话 ID ,服务器能够区分出哪一条消息是来自哪一个客户端,这一点对于重复消息的去除和并发的客户端间的区别至关重要。

事务语义支持的日志
一个事务性的运行环境确保一个应用程序的原子性、一致性、孤立性和持久性。这使得并行运行的应用程序在访问共享资源时得到保护,避免由于资源冲突而产生的资源冲突甚至崩溃。如果一个应用程序发生崩溃,那么他的所有操作将会被回退(原子性),如果一个应用程序成功,那么他的所有操作将被保证成功(持久性)。事务系统能够确保资源保持一致性,即使资源被同时访问(一致性)。事务系统同样能够保证应用程序的运行可以不管其它应用程序的运行情况,就像它自己在单独运行一样(独立性)。

日志对许多应用程序来说是都是一个重要的组成部分,至少存在两种类型的日志。 一般信息日志主要用来跟踪应用程序的步骤和操作。根据日志信息的用途,它对应用程序的操作有着或轻或重的影响。例如, 如果日志记录只是用来进行统计分析,少数几次失败的日志操作将是可以接受的。然而,如果日志是用来审计, 那么遗失日志记录将是不可接受的。

另外一种日志称为关键业务日志。它将影响到应用程序中与业务相关的其它部分。其它应用程序将读取关键业务日志并应用到它们的商业逻辑中。这种类型的日志将像其它的一些业务操作一样来被谨慎处理。例如一个财务日志记录,里面记录财务转帐信息,而且这一日志被用来进行投资兴趣分析或纳税凭证。

在本文中,我们定义了一个事务语法支持的日志服务,重点解决原子性语法。者并不意味者我们强制所有的日志行为做作为原子事务的一部分,而是根据日志信息是否事务敏感,我们可以给应用程序提供相应的事务语法支持。

事务性执行
如果有几个应用程序在并行运行,它们中的每一个都要执行一系列连续的操作,那么整个系统的执行过程就包括按照一定次序执行的、来自不同应用程序的不同操作。如果这些应用程序访问共享数据,它们就将导致破坏一致性的潜在冲突的产生。数据库系统中的一致性概念和预测锁定(请参阅 参考资料)对并发环境中的一致性问题给出了明确定义。数据库系统的并发控制和复原(请参阅 参考资料)给出了防止系统产生不一致问题的正确操作的属性。

原子性
原子性可能是一个成功事务执行的最基本属性。一个事务执行被称为一个原子是指它的所有更新操作要么全部成功,要么全部失败,这一点通常被称为 all-or-nothing 属性。如果你假设一个事务总是一个一致性的工作单元,整个系统的所有更新都被执行,很显然系统仍能够保持一致性。当一个事务执行已经开始执行但尚未完成,只有一部分更新操作被实际执行,你就不能假定整个系统的状态仍旧是一致的。你只有在系统的所有操作都被执行或都不被执行时,才能假设整个系统是一致的。

作为事务的基本属性,原子性被各种系统实现。在分布式系统中,原子性还表明一个事务应该在参与事务的所有节点中全部执行成功或全部失败。为确保这一点,两步提交协议(请参阅 参考资料中的 分布式数据库原理)被提出且在各种系统中实现。#p#副标题#e#

原子性日志操作
你可以将日志操作分为以下 3 类:

  1. 不涉及事务原子性的日志操作。一个日志操作的失败不会导致整个事务的失败,并且即使在事务被中止的情况下日志操作仍旧可以成功。这类日志操作不需要消耗事务管理资源,也不需要日志服务支持事务
  2. 可视为其它更新一样参与原子事务的日志操作。如果操作失败,整个事务过程需要回滚,并且只有在整个事务执行成功的前提下,日志操作才视为成功执行。
  3. 半事务原子性的日志操作。只有当事务提交的时候日志操作才会成功,但日志操作的失败并不会导致事务被中止。在那种情况下,一些日志记录将会丢失,但日志存储并不会因为被中止的事务的记录而被“污染”。换句话说,并不存在脏写的记录。这种操作类型是在原子性和事务带来的巨大代价之间的折中。因为如果日志操作失败,并没有正常的事务操作受到影响,但如果事务失败,日志消息却会受到影响。

对于分布式计算来说, Web 服务是一个相对较新的消息基础设施。 Web 服务的事务性还没有得到相应的重视。最近, Web 服务组织就分布式事务如何与 Web 服务架构相协调提出 2 个草案 (商业事务和 Web 服务事务 -- 请参阅 参考资料)。这里我们不对这两个草案进行比较,相反,我们主要讨论 WS-Transaction 规范,因为它是一个更有发展前景的方案,但我希望你将这两个草案都阅读一下来形成你自己的观点。WS-Transaction 规范在分布式事务的参与者间定义了一个两阶段提交协议来支持事务原子性。

WS-Transaction
WS-Transaction 规范应用于基于 Web 服务的分布式系统。应用程序之间、应用程序与系统服务之间以及系统服务之间都是通过 Web 服务进行通信。规范以 Web 服务描述语言描述了原子性事务协议。协议内容如下:

  • 完成: 应用利用此协议来初始化分布式事务提交循环。
  • 两阶段提交: 首先参与分布式事务的应用程序必须延缓自身的更新。当完成指令被请求,一个协调器将向所有的事务参与应用程序发出一个 Prepare 消息。在接收到 Prepare 消息后,每个应用程序根据被延缓的更新是否可以提交来返回 Prepared 消息或 Aborted 消息。如果事务的所有参与者返回的都是 Prepare 消息,则它们将得到一个提交指令,这将导致所有的更新被提交,否则它们将得到一个放弃消息,所有被延缓的更新将被放弃。
  • 阶段 0: 一旦一个两步提交循环开始,应用程序除了 Prepare 、Commit 和 Abort 指令外,不再执行任何操作。假设一个在缓存中包含若干更新的服务最终需要将更新存储到数据库中,那么它将需要调用一个数据库服务。由于应用程序在接收到 Prepare 指令后将禁止调用数据库服务,那么服务如何在 Commit 之前存储数据呢?这将通过阶段 0 协议来实现。在开始 Commit 循环之前,协调器将给参与者发送一个阶段 0 消息。
  • 结果通知: 一些不属于分布式事务的应用程序仅仅想知道事务执行结果:提交还是放弃。它们可以通过结果同志协议获取这一信息。

WS-Transaction 规范建立在另外一个协议 WS-Coordination(请参阅 参考资料)之上. 上述 2 个协议都是以协议协调器和协议使用者之间的 Web 服务接口的形式来实现的。因此,存在必然存在两阶段提交协调服务和两阶段提交使用服务,阶段 0 协调服务和阶段 0 使用服务等等。这些协调服务和参与服务在 WS-Transaction 规范中通过 Web 服务描述语言( WSDL)以端口类型的形式来描述。

事务支持的日志服务架构

图 5: 事务支持的日志服务架构
事务支持的日志服务架构

图 5 展示了一些参与节点和协议以及它们之间必要的交互。我们假定有 2 个应用程序节点( Appl1 和 Appl2 ),一个数据库节点( DB ),和一个包含日志服务的节点( LogService )。

节点及其服务

  • Appl1 是一个初始应用程序,它希望完成分布式事务,因此它向协调器注册事务的完成协议。因此它将参与服务提供给完成协议( P-C )并使用协调器的服务来使用完成协议。它同样可以使用日志服务节点上的日志服务( Logging ),发送不同事务原子级别的日志信息。另外,它还向节点 Appl2 发送应用程序信息,向数据库节点 DB 发送数据库请求。
  • Appl2 被 Appl1 初始化并为 Appl1 工作。它在本地内存中缓存了许多更新,并希望最终将这些更新输送到数据库中,因此它通过协调器注册阶段 0 协议,因此必须将提供参与服务给阶段 0 协议 ( P-pz )。
  • DB 是数据库节点,它负责接收应用程序的更新,因此它作为一个参与者来注册两阶段提交协议。因此它必须提供参与服务( P-2pc )。
  • LogService 是一个日志服务节点。它负责接收日志服务,每一个日志消息可能具有不同的事务原子级别。如果某个日志消息是事务原子性或半事务原子性,日志服务必须作为一个参与者来注册两阶段提交协议,这样她就必须提供参与服务给两阶段提交协议( P-2pc )。根据不同的缓存策略,它可能还需要注册阶段 0 协议来将日志消息存储到数据库中在事务完成之前。
  • Coordinator 是一个 WS-transaction 协调节点,它提供如下协调服务:完成协议、阶段 0 协议、两阶段提交协议、C-c、 C-pz、 和 C-2pc。

消息顺序
由于篇幅限制,我们这里对参与者与协调器之间的协议注册消息不加讨论,你可以在 WS-Coordination 规范(参见 参考资料)中获取更多相关信息。在随后的讨论中,我们假定每一个节点对于它使用的协议都已经成功的注册了协调器。

必须说明的是,对于 WS-Transaction 定义的每一条消息,都同时还包含一个事务协调上下文。因为当消息通过 Web 服务环境传输时,事务协调上下文被包含在 SOAP 头中,规范中的上下文具有可扩展性,你可以通过一个代表日志消息所需的事务原子性级别的元素来对它进行扩展。这个指定的级别可以是空、半原子性和原子性。需要注意得是,任何消息都包含事务协调上下文,不管是应用程序间的消息还是应用程序发送给数据库的消息。

  1. 应用程序与应用程序间存在消息,应用程序与数据库服务间存在消息,应用程序到日志服务间存在消息。每一个日志消息在事务协调上下文都包含指定的事务原子性级别信息。日志服务器总是检查这一信息。如果指定的级别是原子性或半原子性,日志服务不会将日志消息马上进行持续化处理,相反,它将这些日志信息保存在安全的地方,在提交过程中再将这些信息取回。如果事务原子性级别是空,日志消息将被立即写入永久性日志媒体中。
  2. 节点 Appl1, 初始化应用程序,决定完成工作,因此调用协调器的完成服务 (C-c)。
  3. 在初始化两阶段提交循环之前,协调器调用 Appl2 的阶段 0 参与服务。作为对此消息的响应, Appl2 通过数据库服务写入缓存的更新并将这一阶段 0 的成功报告给协调器。如果 Appl2 没能够完成阶段 0 ,协调器将会取消整个事务。
  4. 如果阶段 0 成功,协调器将开始两阶段提交循环:
    • 协调器调用 LogService 和数据库服务器的 Prepare 操作。日志服务器检查日志服务是否准备好将所有事务原子性(不是半事务原子性)的日志消息持久化,如果检查失败,将向协调器报告 Abort 信息,否则报告 Prepared 信息。向协调器发送 Prepared 消息就好比作个可以提交的承诺,因此事务原子性的日志消息必须预先存储到稳定的存储器,这样 随后的提交即使日志服务在期间崩溃仍旧可以完成。
    • 如果每个参与者报告 Prepared,协调器将向每一个参与者发送 Commit 消息。然后日志服务器持久化所有事务原子性和半原子性的日志消息。如果持久化顺利完成,则向协调器报告 Commit。

协调上下文
在 WS-Transaction 规范中协调上下文被定义为一个事务相关的头信息的容器, 清单 1 给出了 SOAP 头中的协调上下文的结构。上下文结构包含一个元素 , , 指定上下文的类型,它是一个 WS-Transaction URL。它说明这一协调器上下文包含一个 WS-Transaction 协议消息 。在上下文内部,我们引入新的元素 , ,其中的命名空间是假定的,元素的值是日志信息指定的事务原子性级别,它可以是空、原子性或半原子性。

清单 1




 
. . . 
 
   2002-06-30T13:20:00.000-05:00  
  http://Fabrikam123.com/SS/1234
  
      http://schemas.xmlsoap.org/ws/2002/08/wstx 
  
   
  
      http://Business456.com/registration               
   
  ...
   
  semi-atomic 

... 

结束语
这篇文章指出日志是现代业务应用程序中的一个重要部分,需要像应用程序中其它的与业务相关的部分一样谨慎处理。如果业务需要日志作为企业及其处理流程的一部分,那么一个集中的日志服务便应需而生,因此日志 Web 服务是一个理想的选择。

热词搜索:

上一篇:如何彻底清除本地和远程系统日志文件
下一篇:交换机策略路由配置的应用

分享到: 收藏