SOA 最佳实践:BPEL 简明手册

第 10 部分:使用 BPEL 进行可靠处理
作者:Michael Cardella 和 Jeremy Bolie

了解如何使用 BPEL 构建高度可靠的可重用业务流程。

 查看完整的“BPEL 简明手册”索引

 

本文相关下载:
 示例代码
 Oracle BPEL 流程管理器

 

2006 年 3 月发布

随着企业内部 Web 服务和 BPEL 流程的激增,服务质量成为是否采用特殊服务的决定因素。如何确保服务实现所请求的功能,而不受各种障碍(如网络故障或应用程序不可用)的影响?服务能否在不同的业务流程中使用?所有这些问题的答案将决定某个特定业务流程的可重用性。业务流程的可靠性越高,跨多个应用程序的流程的可重用性就越高。

在 BPEL 简明手册的本部分中,我们将介绍一个由多个应用程序组成的业务情形。该情形演示了能够提供可靠功能的 BPEL 流程的必要性,以及如何在不同的业务情形中多次使用此 BPEL 流程。然后,本文将引导您逐步构建一个通过智能重试逻辑提供此高质量服务的 BPEL 流程。此外,您还将了解如何通过出色的异常管理、基于电子邮件的通知以及错误记录来增强此流程。

业务情形

服务可重用性是任何面向服务体系结构 (SOA) 策略的基石。只有能够创建一组可重用服务,企业才能从 SOA 实施中取得真正的价值。这些服务随后将由不同的部门或应用程序在不同的业务环境中使用。除了所提供的实际业务价值以外,服务的成功情况还将推动特定服务的可重用性。服务的故障率是多少?服务能否克服网络中断?服务是否足够灵活,从而实现错误与异常恢复?服务完成请求作业的可靠程度越高,服务在不同业务环境中得到使用的可能性就越高。

看一看图 1 所示的情形:企业需要向不同合作伙伴提供产品的技术文档。文档的访问级别取决于合作伙伴类型以及所请求的产品文档。该信息存储在 Oracle 数据库中。随着合作伙伴加入和离开网络,需要通过多个企业应用程序中的相应审批和更新来修改提供的信息(添加/更新/删除访问权限)。

 

图 1
图 1 授权提供环境


在授权数据库中激活、禁止和修改授权后,必须向 Documentum 发送通知。授权更改的发送顺序必须与其创建顺序一致。必须确保消息的完整性,并且必须维护完整的审计日志并将其记录到中央应用程序数据库日志中。

BPEL 在编排授权激活和禁止方面起到至关重要的作用。此 BPEL 流程将与 TIBCO 消息传递总线紧密协作,以便可靠地向 Documentum 传递消息。它还将负责错误记录和通知。该流程执行任务的效率和可靠性必须足够高,以免因网络中断或 Documentum 应用程序不可用而中断。它应能够不断的尝试操作,直到完成其任务。如何开发能够进行可靠处理的类似 BPEL 流程?

本文的余下部门将详细介绍一个使用 BPEL 提高服务处理质量的策略。创建数据处理重试的关键因素在于数据库。该策略只是用于提高在 BPEL 中运行的流程的可靠性和服务质量这一方法的一部分。

体系结构

下面,让我们了解一下此 BPEL 流程的设计逻辑。

 

图 2
图 2 BPEL 流程逻辑


此 BPEL 流程(从数据库中读取记录并对其进行处理)由 Oracle BPEL 的数据库轮询适配器启动。此 BPEL 流程最后几个操作之一是向数据库报告成功或失败。随后,数据库过程将根据重试尝试的状态和次数来确定是否需要重试该流程,如果确实需要,则将记录重新安排为在将来获取。该流程的最后一步是调用日志服务。除了在数据库中创建日志条目以外,该服务还使用一组规则来确定给定流程中具有某种状态的消息是否应发送通知。如果应发送通知,则它还将选择要使用的电子邮件模板和电子邮件发送列表,邮件中将包含日志中的相应信息。

无论是在问题可以自动更正的情况下,还是在需要人力参与解决问题的情况下,该方法均可以提高可靠性。与合作伙伴重试不同,该方法重试 BPEL 流程的整个执行过程。它的功能丰富,并不仅限于在 BPEL 中创建一个简单的重试循环。

该处理模型易于从外部进行监控和交互。如果在数据库中管理流程的创建日期和上次修改日期,则可以对该数据库运行查询以判断
  • 哪些记录尚未由 BPEL 获取
  • 哪些记录未能及时完成处理
  • 哪些记录已经终止

此外,启动已终止记录的重试以及加速计划的重试也很简单。

在实施以上设计时应执行以下三个重要操作:
  1. 将已处理的记录的状态存储到数据库中。该状态包括流程状态、下一个流程尝试时间以及处理尝试计数。
  2. 创建一个可更新视图(只公开可以处理的记录)。由于数据库适配器无法处理与 SYSDATE 进行比较的 where 子句,因此需要使用视图。
  3. 设计用于确定是否重试出现故障的流程以及何时进行重试的逻辑。该信息将在数据库中使用存储过程更新。也可以使用更新合作伙伴链接以及 BPEL 中的其他逻辑执行该操作。

在下一个部分中,您将了解如何构建这样的流程。

构建该示例

下面我们将构建以上介绍的流程。首先,请创建数据库表以支持该流程,然后使用 BPEL PM Designer 建立该流程的模型。

创建数据库对象。由于该流程将重试状态存储到数据库中,因此在创建 BPEL 流程之前需要设计数据库组件。如上所述,需要向数据库中添加的内容包括

  • 更多用于跟踪已处理记录的状态的字段
  • 可更新视图
  • 状态过程
可以向包含修改数据的行或与主要表保持一对一关系的并行表中添加其他字段。应添加的主要列包括
  • Status
  • Process Not Before
  • Retry Count
  • Create DTS
  • Last Modified DTS

状态字段与 BPEL 的数据库轮询适配器标识未处理记录所使用的字段应为同一字段。创建一个规范很有帮助,因为这样做便于标识仍进行处理的记录、已经成功完成的记录以及在出错情况下完成的记录。实现的方法有数字或前缀规范。请查看示例代码下载中的 CREATE_TB_DB_POLL_SOURCE.sql。

该视图应只公开其 Process Not Before 列条目早于当前 SYSDATE 或为空的记录。通过该视图还可以轻松地限制应处理的记录数。此外,该视图还可以只公开要处理的记录的主键,从而使视图更简洁。查看随附示例中的 CREATE_VW_ DB_POLL_SOURCE_VW.sql。

状态过程应包含一个用于指示错误的标记,或者也可以使用一个单独的过程来标识错误状态。对于错误状态而言,该过程将标识是否应重试流程实例,以及在需要重试的情况下确定重试时间。随后,该过程应相应地更新记录。一个典型的策略是先进行几次间隔较短的重试,然后再进行大量间隔更长的重试。检查示例代码下载中的 SET_DB_POLL_SOURCE_FAULTED.sql。

然后,请创建实际的 BPEL 流程,以便可靠地处理数据库记录。

创建数据库轮询流程.该操作涉及几个步骤:
  1. 创建一个新的 BPEL 项目
    创建一个空的 BPEL 项目。

     

    图 3
    图 3 创建一个 BPEL 项目
  2. 创建一个数据库轮询适配器
    1. 创建一个新的合作伙伴链接。
    2. 单击 Wizard 按钮。
    3. 选择 Database Wizard
    4. 指定服务名称 DBPolling

       

      图 4
      图 4 创建数据库轮询适配器
    5. 配置数据库连接后,选择 Poll for New or Changed Records in a Table 作为操作类型。

       

      图 5
      图 5 选择操作类型
    6. 导入数据库视图 DB_POLL_SOURCE_VW。
    7. 接受随后几个屏幕中的默认值(本示例中没有 where 子句)。选择列 ID 作为主键。
    8. 对视图执行读取后,该向导需要知道应对记录执行什么操作。选择 Update a Field in the Activities Table (Logical Delete),如下所示。

       

      图 6
      图 6 选择“Update a Field...”
    9. 现在,您将看到 Logical Delete 屏幕。指定要更新的 BPEL_STATE 字段以便从逻辑上删除该行。

       

      图 7
      图 7 指定 BPEL_STATE 字段
  3. 创建一个接收活动
    要向 BPEL 流程中添加接收活动,请执行下列操作:
    1. 将接收连接器拖动到在步骤 2 中创建的 DBPolling 合作伙伴链接。
    2. 将接收活动重命名为“receive”。
    3. 选中 Create Instance 复选框。
    4. 单击接收活动弹出窗口上的变量向导,然后创建一个名为 inputVariable 的变量。

       

      图 8
      图 8 创建一个变量
    5. 单击 OK。

      BPEL 流程将类似如下所示:

       

      图 9
      图 9 到目前为止的 BPEL 流程
  4. 添加自定义故障定义
    添加自定义故障的前提条件是包含故障定义的 WSDL 必须由某个合作伙伴链接的 WSDL 引用。尽管可以修改任何合作伙伴链接的 WSDL,但如果重新运行该向导,则将重新生成该合作伙伴链接的 WSDL。这意味着如果重新运行该向导,则需要重复向 WSDL 中添加导入的步骤。

    要将 BpelFault.wsdl 添加到项目文件夹,请执行下列操作:

    1. 在 Oracle JDeveloper 中选择该项目,选择“File/Add to DB_to_JMS.jpr”,然后选择要添加的 BpelFault.wsdl。
    2. 将以下行添加到 DBPollingService.wsdl 中的打开的定义标记之后和 types 元素之前。
      <import namespace="http://schemas.oracle.com/otn/bpel/sample/dbpoll/jmspub/fault" 
      location="BpelFault.wsdl"/>
      

    该 WSDL 对数据的每个部分使用 message part,而不是一个 complex 元素,从而使用同一故障定义作为 BPEL 的默认返回类型。如果 WSDL 没有 message part 部分,BPEL 将创建一个 RPC 样式的 Web 服务,而非文档样式的 Web 服务。

  5. 创建 BPEL 流程的余下部分
    下面我们将将不准备逐步完成构建 BPEL 流程的余下步骤,我们将了解一下最终流程的情况,然后获得各个元素,。整个 BPEL 流程如下。

     

    图 10
    图 10 整个 BPEL 流程

 

下面看一看此 BPEL 流程的各个元素。主要部分包括

  • 初始块(位于流程作用域中)
  • 处理
  • 回复/报告最终状态
  • 记录
  • 重新引发故障

初始块

这是处理作用域中的第一组任务。顾名思义,它负责流程初始化以及设置全局变量、错误变量和日志变量。如图 11 所示, 示例代码下载中包含下列活动。

 

图 11
图 11 初始化流程的步骤流


  • Checkpoint(可选)
    检查点强制脱水。尽管它略微降低了执行速度,但可以保证启动的每个 BPEL 流程实例将显示在控制台中。

    BPEL 控制台只向最后一个脱水点显示执行状态。某些错误将终止执行而不允许向控制台报告状态。此外,某些合作伙伴链接同步调用可以无限期地处于等待状态,而不允许报告脱水状态。

  • global_init
    它用于初始化几个由异常处理机制使用的“常数”。该活动应在流程开始之前执行,即在任何有可能引发故障的操作之前执行。
  • init_log
    init_log 任务在 Java 中初始化一个时间,以便可以轻松地跟踪相应的处理时间(精确到毫秒)。仅当流程集成的日志系统将收集精确到毫秒的执行时间时才需要该任务。

处理

现在,我们将了解一下处理核心。看一看下面的 BPEL 流程流。

 

图 12
图 12 BPEL 流程流


流程流。初始化变量后,该流程开始读取数据库。它将当前状态更新为“processing”,然后读取数据库记录。验证数据的正确性后,它将转换消息以将其传递到目标。在将消息发送到目地的之前,它将数据库中的当前状态更新为“sending”。最后,它将消息发送到目标(在该示例中为 JMS 总线)。如果流程长时间运行或存在一些关键的风险区域,则流程在遍历流中的关键点时更新数据库中的状态这一方法尤其有用。读取数据库操作(ReadDB 合作伙伴链接)已经与启动流程的视图(DBPolling 合作伙伴链接)分开。这使视图比较简单,并消除了无法对 BPEL 中的视图使用连接的限制。

异常处理。较大的作用域中包含的每个作用域可以捕获所有异常并抛出内部定义的故障。例如,如果在读取数据库记录期间出现错误,则作用域将捕获该错误,将错误状态设置为“Error while trying to read in data to be processed”并将该错误抛到父作用域。这意味着每个故障均定位到更精确的级别。

每当主要处理的内部出现错误时,均会抛出内部类型的故障。随后,外部捕获块将捕获该故障。使用该策略时,应注意不要在 catchall 块中捕获自定义故障,因为这会导致丢失所有定制故障信息。如果在作用范围内部抛出了定制故障,则除了使用将捕获任何其他错误的 catchall 块以外,还将使用捕获该特定故障的 catch 块。

可重用性.必须注意的是,处理逻辑基于业务需要。在本情形中,该流程将消息可靠地传递到 JMS 目标。但在实际环境中,处理方法可能有所不同,其中既包括更新银行帐户,也包括创建新客户,还包括同步订单数据。该流程提供的可靠性保持一致。此外,还可以可靠地重用该流程。

回复/报告最终状态

 

图 13
图 13 描绘最终状态更新的流


处理状态在数据库中更新为 SUCCESS 或该流程执行过程中遇到的故障(如上所示)。尽管该更新是可选的,但仍建议您启用外部应用程序来监视所有流程实例从头到尾的进度。

本示例使用数据库过程(SetFaulted 合作伙伴链接)来报告最终状态。尽管可以在 BPEL 内部进行报告,但延迟对数据库过程的更新可以简化 BPEL 流程。

指示最终状态为 unsuccessful 的报告将触发流程重试。如果重试流程的次数未达到最大次数,则将在某个间隔过后重试该流程。

记录

记录流程收集处理信息并将其发送给集中化的记录程序。该信息最重要的部分是错误的严重等级和消息代码。记录具有以下优点:

  • 它生成一个可以通过数据库轻松搜索到的审计日志。
  • 严重等级和消息代码决定是否发送通知。
  • 消息包含信息的某些重要方面,如 BPEL 进程实例以及启动处理的行的主键。这使故障排除程序可以在 BPEL 控制台中快速找到该进程,或在数据库中找到数据。

重新抛出故障

 

图 14
图 14 为找出错误流程而抛出故障


如图 14 所示,最终的重新抛出故障简化了有问题的流程实例的查找。可以轻松地在 BPEL 控制台中找到这些流程。当最终重新引发故障时,流程实例将在控制台中得到标记,您也可以过滤以只显示结束时出现故障 (Canceled) 的流程。

BPEL 流程开发到此结束。该流程应与其他实践组合使用以提供最佳的可靠性;例子包括数据库监控、同步事务以及日志监控。该流程使您可以轻松地标识已经成功、最终出现故障或未及时完成其处理的记录。所有这些信息对于实际的业务环境很有帮助,实际业务环境中处理的每个记录可能价值数千美元,而违反 SLA 可能导致客户不满。

结论

文本演示了如何构建一个高度可靠地执行其任务的可重用业务流程。您构建的流程可以可靠地向 JMS 目标发送消息,并且由于它的可重用性很高,因此还可以使用它可靠地提供任何业务功能。

所有业务异常均无法在 BPEL 流程中捕获。提供高质量服务并不仅限于流程级别。必须将其与高效的审计日志监控、通知相应的相关人员、在数据和流程级别排除异常以及在每个处理阶段实现透明性相结合。任何可靠的流程均应满足所有这些要求。

 


Michael Cardella Michael Cardella 是 Qualcomm CDMA Technologies (QCT) 的高级工程师。Michael 在自定义应用程序开发小组工作,主要从事 Web 服务以及与业务流程相关的应用程序开发。此前,他曾担任过领先级 Web 服务安全性和管理产品的主要设计师。

Jeremy Bolie Jeremy Bolie 是 QCT 的高级 IT 经理,他负责管理自定义应用程序和 Documentum 开发小组。Jeremy 在 Java 和 Oracle 技术方面具有 10 年以上的工作经验,从 1990 年年底开始一直从事 Web 服务和面向服务体系结构方面的工作。

 

将您的意见发送给我们