WPS 和 WebSphere ESB中的异常处理
2010-09-27 08:16:37 来源:WEB开发网本文阐述如何在 WebSphere Process Server 和 WebSphere Enterprise Service Bus 中捕获并处理错误条件,并介绍问题检测、重试行为、异常传播和报告。本文假设您熟悉服务组件体系结构(Service Component Architecture,SCA)编程模型,并具有使用 WebSphere Process Server 和 WebSphere Enterprise Service Bus 开发应用程序的经验。
引言
在生产环境中运行企业应用程序时,了解故障条件下系统的行为非常重要。本文介绍 IBM® WebSphere® Process Server(以下称为 Process Server)和 IBM WebSphere Enterprise Service Bus(以下称为 Enterprise Service Bus)中的异常的基本类别。本文介绍:
系统在遇到问题时有何行为
在何处记录问题
如何从各种问题中恢复
SCA 入门知识
在深入研究错误处理之前,您需要了解服务组件体系结构 (SCA) 的一些基础知识,其中包括接口类型、调用模式和异常类别。
接口类型
SCA 支持两种接口类型:
JTtype 使用 Java™ 接口定义 WType 使用 WSDL 端口类型定义
该类型用于描述接口和引用。使用引用的客户端编程人员必须与基于类型的引用交互。调用或服务提供程序的目标是可以使用引用方式不同的类型(J 类型或 W 类型)。SCA 将消除该差异。
可以在 JType 和 WType 接口上声明业务异常。JType 接口使用一个抛出子句,而 WType 接口则是声明错误。
调用模式
SCA 提供以下两种调用样式:
同步 阻止对目标进行的请求和在同一线程上返回的响应。 异步 不阻止进行的请求,并在单独的线程中提供响应。
在异步样式中,SCA 异步编程模型提供三种类型的异步调用模式:
单向 作为“即发即弃”(Fire and Forget) 调用模式使用。客户端调用通过引用提供的操作,并立即返回控制。不返回任何响应、异常或错误。 延迟响应 请求–响应异步调用模式。客户端进行请求,并在客户端适宜时间请求响应。 回调 请求–响应异步调用模式。当响应准备就绪时,客户端实现由 SCA 运行时调用的回调接口。
了解调用模式之间的差异对理解您可能面临的错误条件至关重要。
异常类别
在 Process Server 和 Enterprise Service Bus 中,应用程序是使用 SCA 编程模型构建的。它定义两种类型的错误条件:业务异常和系统异常 – 在编程模型中称为 ServiceBusinessException 和 ServiceRuntimeException。
业务异常
业务异常是在 业务方法的函数签名中声明的、经过检查的异常(WSDL 错误或 Java 抛出)。使用业务异常可标识应用程序或服务预期的错误条件。一个示例是用于股票报价服务的 InvalidSymbolException。此类异常由 ServiceBusinessException 包装,并传递回客户端。
系统异常
系统异常也称为运行时异常。它们 不是在方法签名中声明的。通常,它们表示应用程序无法预知的错误条件,如 Java 组件中的 NullPointerException。这些异常由 ServiceRuntimeException 包装,并传递回客户端,该客户端可以查询 ServiceRuntimeException 来确定原因。
在 SCA 编程模型中,将一些内置系统异常定义为 ServiceRuntimeException 的子类:
ServiceExpirationRuntimeException 指示异步 SCA 消息已过期。可以使用服务引用上的 RequestExpiration 或 ResponseExpiration 限定符设置过期时间。 ServiceTimeoutRuntimeException 指示在指定的时间限制内不接收对异步请求的响应,该时间限制是在使用延迟响应异步通信模式时,在 invokeResponse() 调用过程中以编程方式设置的。 ServiceUnavailableException 指示在通过导入调用外部服务时抛出异常。 ServiceUnwiredReferenceRuntimeException 指示组件上的服务引用连接不正确。
异步调用的异常处理
当同步调用服务组件时,客户端和服务提供程序在同一线程中执行。目标可以向客户端返回响应消息、异常返回,或者不返回任何内容(在单向操作中)。如果结果为异常,则它可以是业务异常或系统异常。本例中的客户端可以是应用程序代码或系统代码的某一形式。
图 1. 调用组装图
下面是一个示例客户端,它调用使用 JType 接口声明的 Java 组件。该接口具有一个按以下方式声明的方法:
清单 1. 股票报价接口
public interface StockQuote {
float getQuote(String symbol) throws InvalidSymbolException;
}
客户端代码与以下内容类似:
清单 2. 股票报价同步客户端报价
try {
float quote = StockQuoteService.getQuote(String symbol);
} catch (InvalidSymbolException s) {
System.out.println(This is business exception declared in the Java interface.);
} catch (ServiceRuntimeException e) {
System.out.println(Unchecked system exception detected);
}
在上面的场景中,第一个异常 InvalidSymbolException 指示请求已到达不能识别客户端输入的服务提供程序。服务提供程序然后抛出业务异常,指示提供的符号无效。此业务异常就是方法签名声明的唯一异常。
客户端使用 Jtype 引用仅捕获 JType 异常(如 InvalidSymbolException)。对于使用 WType 引用编程的客户端,您可以下载下面的 WSDL 示例。
除声明的业务异常外,客户端还可以接收系统异常。例如,如果股票交易系统遇到问题,则该服务可能因某种未经检查的异常而无法获得报价。当该服务抛出此类异常时,ServiceRuntimeException 将返回到客户端,客户端然后可能要确定基本原因。下面的代码段显示了如何获取此信息:
清单 3. 股票报价同步客户端报价 II
try {
float quote = StockQuoteService.getQuote(String symbol);
} catch (ServiceRuntimeException e) {
Throwable t = e.getCause();
if (t instanceof RemoteException) {
system.out.println(System ran into RemoteException. Details as follows: + e.toString());
}
异步调用的异常处理
如上所述,SCA 编程模型支持三种类型的异步调用模式。当异步调用服务组件时,客户端和服务提供程序是在不同的线程中执行的,并且错误条件可能在任一线程中发生。在调用过程中,客户端可能遇到系统异常,或者在服务于请求时,服务提供程序可能遇到业务异常或系统异常。
在 Process Service 或 Enterprise Service Bus 中,始终存在上面所示接口的异步对等项:
清单 4. 异步股票报价接口
public interface StockQuoteAsync {
public Ticket getQuoteAsync(String arg0);
public Ticket getQuoteAsyncWithCallback(String arg0);
public float getQuoteResponse(Ticket ticket, long timeout) throws InvalidSymbolException;
}
下面是在使用延迟响应的调用模式时调用的客户端代码:
清单 5. 异步客户端
Ticket ticket = stockQuote.getQuoteAsync(symbol);
try {
quote = stockQuote.getQuoteResponse(ticket, Service.WAIT);
} catch (InvalidSymbolException s) {
System.out.println(This is business exception declared in the interface.);
} catch (ServiceRuntimeException e) {
System.out.println(Unchecked system exception detected);
}
与同步调用类似,InvalidSymbolException 指示 请求已到达服务提供程序,该提供程序抛出业务异常,指示符号无效。此业务异常就是接口声明的唯一异常。
另外,客户端使用Jtype 引用仅捕获 JType 异常(如 InvalidSymbolException)。对于使用 WType 引用编程的客户端,您可以下载下面的 WSDL 示例。
除声明的业务异常外,客户端还可以接收系统异常,如发送消息时发生的连接错误。客户端不能接收服务线程(异步调用的服务端上的线程)中发生的系统异常。根据 SCA 异步编程模型,在目标组件发生的运行时异常不返回到源组件。下面将介绍这些错误的路由。
关于异步异常处理的异常情况
SCA 异步编程模型规则的一个异常是在目标组件发生的运行时异常不返回到源组件。如果源组件是业务流程组件或员工流程,则在目标服务组件中发生的系统异常都返回到调用程序。业务流程设计人员使用此功能可以模拟和捕获系统异常,并在 BPEL 客户端返回系统异常时执行错误逻辑。
重试配置
SCA 使用服务集成总线在组件之间传输消息。将模块安装到 Process Server 或 Enterprise Service Bus 服务器时,安装任务将创建这些目的地。在调用过程中,如果目标服务组件返回系统异常,则在到达模块目的地上的阀值之前,服务集成总线自动重新提交消息。本部分阐述如何查看和编辑此重试设置,并介绍忽略此设置时的特殊条件。
重试示例
假设名为 StockServiceModule 的模块包含两个组件:Validator 和 Calculator。Validator 对 Calculator 进行异步调用。异步调用生成消息,并将其放入服务集成总线中。调用 Calculator 服务的 SCA 调用框架稍后拾取此消息。在本示例中,假设软件缺陷导致 Calculator 抛出 NullPointerException(因为输入参数为空):
图 2. StockServiceModule
从 Calculator 返回 NullPointerException 时,SCA 回滚当前事务,这会导致调用消息放回到服务集成总线上,并放入表示目标服务所属模块的目的地中。在我们的示例中,模块名称为 StockServiceModule,所以消息回滚到的目的地名称为 sca/StockServiceModule。在缺省情况下,服务集成总线尝试将同一消息提交给 Calculator 服务的次数为最多 5 次,但您可以设置重试的次数。
更改重试设置
如上所述,服务集成总线拥有内置重试机制和 SCA 消息驱动 Bean (MDB)。您可以通过修改模块目的地上的 Maximum Failed Deliveries 属性来配置重试行为。假设您的模块名称为 StockServiceModule,并且 SCA 创建的一系列服务集成总线目的地(其中一个名称为 sca/StockServiceModule)都支持异步通信。若要更改在异步服务调用失败时的重试次数,则应更改 Maximum failed deliveries 的值:
标识目标组件驻留的模块。本示例中为 StockServiceModule。
从管理控制台找到 SCA 系统总线,它通常遵循以下命名约定:SCA.SYSTEM.$cellName.Bus。例如 SCA.SYSTEM.widcell.Bus 是单元测试环境的缺省总线。
导航到与此总线关联的目的地列表。
找到具有名称(如 sca/$moduleName)的目的地。在本示例中,我们查找的名称为 sca/StockServiceModule。
从模块目的地的属性屏幕中找到字段 Maximum failed deliveries,并将其设置为大于 2 的所需整数。在 Enterprise Service Bus 和 Process Server 中,值 0 和 1 无效。
图 3. 配置最大失败提交次数
当重试配置不工作时
如果在 Calculator 实现内部插入打印语句,则重新提交的数量有时并不总是与配置值匹配。以下两个功能可以导致此偏差:
JMS 导出
如果请求包括在 JMS 导出和组件之间传递消息,则重试的次数总是比配置值多 1。下图显示了如何使用目的地将消息从 JMS 导出路由到组件:
图 4. JMS 导出
从模块的外部目的地拾取消息,并将其提交到目标组件(本例中为 Pojo1)。
Pojo1 抛出系统异常。
将消息回滚到拾取的地方。在本例中,SCA 模块目的地的名称为 sca/Module1。
将消息回滚到目的地后,基础系统基于目的地的最大失败提交次数设置重新提交消息:
图 5. JMS 导出 II
将消息重新提交给 JMSExport1。
JMSExport1 绑定会检测重新提交的消息,并将该消息放入 sca/Module1/component/Pojo1 目的地。
将消息转发到 sca/Module1,并提交给 Pojo1。
Pojo1 抛出系统异常
将消息回滚到 sca/Module1。
从这里再将消息重新提交给 Pojo1,提交次数为 4 次。
结果是 Pojo1 被调用 6 次,比 sca/Module1 的最大失败提交值多 1。
业务流程组件
业务流程组件调用目标服务组件时,目标线程遇到的任何运行时异常都被提交回流程组件。下面是处理运行时异常的事件顺序。
图 6. 业务流程组件
流程组件将消息提交给外发目的地之前,它会标记所有系统异常应返回到调用程序的消息,以便进行处理。
将消息放入 sca/Module2/component/Pojo2 目的地。
从 sca/Module2 拾取消息,并提交给 Pojo2。
Pojo2 抛出系统异常。
将消息回滚到 sca/Module2。
在这里,基于缺省最大失败提交次数设置值 5(1 次原始提交加上 4 次重新提交)将消息重新提交 4 次。
在第 4 次重试(第 5 提交)时,消息被 SCA 中断,并将消息和故障原因一并提交回调用程序,所以在最后的消息重新提交过程中,Pojo2 始终不被调用。
结果是对 Pojo2 调用了 4 次,比 sca/Module2 的最大失败提交值少 1。
失败的消息位于何处?
Enterprise Service Bus 中失败消息的路由规则
在异步调用过程中,当目标组件发生系统异常时,消息会回滚到传入目的地,并被重新提交。在 Enterprise Service Bus 中,达到重试限制后,消息会按照模块目的地的 Exception destination(异常目的地)字段中的指定路由到异常目的地。此目的地在 SCA 系统总线的系统异常目的地中设置。在缺省情况下,每台服务器有一个系统异常目的地。
对于节点名称为 WPSNode、服务器名称为 server1 和总线名称为 SCA.SYSTEM.WBIDev-BGMNode01Cell.Bus 的环境,系统异常目的地为 _SYSTEM.Exception.Destination.WPSNode.server1-SCA.SYSTEM.WBIDev-BGMNode01Cell.Bus
随着时间的推移,消息在此异常目的地积累,您可以使用管理控制台浏览队列中的消息数。或者,您可以编写 JMS 客户端应用程序从队列中读取进行异常处理的消息。
Process Server 中失败消息的路由规则
在 Process Server 产品中,使用以下命名约定将异常目的地设置为 Process Server Recovery 异常目的地。对于节点名称为 WPSNode 和服务器名称为 server1 的服务器,恢复异常目的地为 WBI.FailedEvent.WPSNode.server1
每台服务器有一个恢复异常目的地。通常情况下,将所有在 SCA 系统总线上创建的常规目的地都配置为将失败消息路由到恢复异常目的地。另一方面,将 SCA 应用程序总线上的常规目的地都配置为将失败消息路由到 SCA 应用程序总线的系统异常目的地。这样,如果 JMS 导出从 SCA 应用程序总线拾取消息,并遇到回滚情况,则失败消息将路由到 SCA 应用程序总线的系统异常目的地,而不是 WebSphere Business Integration 恢复异常目的地。
发生系统故障时,除了在此异常目的地捕获失败消息外,Process Server Recovery 功能还生成表示系统错误的失败事件,并将其存储到恢复数据库。失败事件管理器子系统由一组数据库表、消息驱动 Bean、EJB 和其他 J2EE 构件组成。
失败的事件管理器处理
下图显示了如何创建失败事件:
图 7. 失败事件处理
源组件使用异步调用模式进行调用。
SCA MDB 从 SCA 目的地拾取消息。
SCA MDB 调用正确的目标组件。
目标组件抛出 ServiceRuntimeException。
SCA MDB 事务回滚到 SCA 目的地。
将异常信息存储到未确认其状态的 FEM 数据库。
服务集成总线重试调用 n 次——缺省次数为 5(1 次原始调用和 4 次重试)。如上所述,您可以使用管理控制台更改缺省值。如果 SCA 模块为 M,请导航到 Buses => SCA.SYSTEM.$Cellname.Bus => Destinations => sca/M,并更改 Maximum failed deliveries。
达到重试次数后,将消息移到 FEM 目的地。
FEM MDB 拾取消息,更新数据库中的失败事件,并将状态设置为“失败”。
何时创建失败事件?正如我们提到的,失败事件不是为同步调用创建的,也不是为双向业务流程交互创建的。它们是在客户端使用异步调用模式和服务提供程序抛出 ServiceRuntimeExcpetion 时创建的。如果目标组件是集群成员,则将消息重新提交到同一集群成员,进而完成重试设置。然后,将消息路由到恢复异常目的地,后者特定于目标组件运行的服务器。
高级调用样式确定
到目前为止,我们阐述了在进行同步与异步调用时,对系统异常的处理是大相径庭的。因此,要了解如何处理系统异常,您必须了解对调用使用了何种类型的调用样式。不过,确定调用样式并不总是非常简单。不管调用是同步的,还是独立于应用程序中使用的 API,SCA 动态调用接口都具有以下方法:
invoke() invokeAsync()
可以假设 invokeAsync() 会导致异步调用。不过,对于第一个 API invoke(),解释并非十分简单。当调用目标服务时,如果目标服务拥有异步实现,则系统可以将同步调用切换到异步调用。异步实现的示例包括长时间运行的业务流程和某些类型的导入绑定(如 JMS 导入)。总之,如果目标服务是提供异步实现的一个组件,则将在组件前面插入异步跃点(到目的地的消息序列和反序列):
图 8. 调用异步组件
如果目标服务由异步导入表示,则在异步跃点外发生的任何系统错误都不会报告给客户端。
图 9. 调用异步导入
还需要澄清一下关于同步导入周围的异步跃点的位置。假设您让 POJO 异步调用 Web 服务导入。异步跃点将位于 Web 服务导入的前面。在异步跃点后面发生的任何系统错误都不会报告,所以,如果在调用远程服务时 Web 服务导入遇到 EndPointNotFound 问题,则在失败消息中捕获此错误,并将其路由到异常目的地:
图 10. 异步调用同步导入
消息过期和超时异常
消息过期是以不同方式处理的另一种错误条件。当使用 SCA API invokeResponse(票证和超时)时,您可以传入超时值,以指定在等待响应到达时应阻止线程的时间。如果响应在指定的时间内没有到达,则抛出 ServiceTimeoutRuntimeException。在轮询响应时,此异常仅适用于调用程序的线程。不要将此异常与 ServiceExpirationRuntimeException 混淆。
当 SCA 调用另一个组件时,您可以指定请求过期和响应过期值。将这些属性设置为调用组件的引用限定符。如果在指定的时间内,没有拾取请求消息,则抛出 ServiceExpirationRuntimeException。通过同一令牌,如果在响应过期时间限制内没有收到响应消息,则抛出 ServiceExpirationRuntimeException。可以在调用的调用端或接收端检测这些条件。在接收端检测时,可发送包含异常的响应消息,以通知调用程序。
当进行同步调用时,是否能够接收过期或超时异常?正如前面所讨论的,当同步调用异步组件或异步导入时,沿着调用路径有一个异步跃点。因此,即使同步发起调用,客户端也可以接收 ServiceTimeoutRuntimeException 或 ServiceExpirationRuntimeException。
错误处理示例
您可以下载测试模块,并探索各种异常,其中包括业务和运行时异常,并作为简单的 Java 类型或业务错误抛出异常。本部分将介绍此测试模块。
用于此交互的 BO 和接口是在考虑了 SCA 编程模型的情况下设计的。示例包括实现接口和传递 BO 的两个 Java 组件。
图 11. 错误示例
客户端组件称为 InvocationPatternComp。示例的服务提供程序称为 ErrorComp。
接口
在此示例中使用两个接口。InvocationPatternInterface 由 InvocationPatternComp 公开,并包含一个 start 操作。使用此接口启动测试。它允许您将客户端和服务提供程序之间的交互所使用的调用模式与组件测试所使用的仅同步调用模式分离开。
图 12. InvocationPattern 接口
第二个接口称为 ErrorInterface,由 ErrorComp 公开和实现。该接口包含单向操作和各种请求/响应样式:
图 13. ErrorInterface
业务对象
在此示例中使用两个业务对象。ErrorBO 包含许多字段,这些字段定义客户端和服务提供程序表现的行为。
图 14. 错误 BO
InvocationPatternComp 使用第一个字段集来确定调用哪一个操作和使用哪一个调用模式。
InvocationPatternComp 如何处理错误 BO
属性 | 有效值 | 注释 |
invocationPattern | sync async oneway async deferred response async callback | 确定在调用目标组件时要使用的调用模式 |
operationType | oneway – 调用单向操作。 reqresp – 调用请求响应操作 rrno – 调用没有任何输出的请求响应 rrnowf – 调用没有任何输出但声明错误的请求响应操作。 | 确定目标接口上要调用的操作 |
exceptionType | Business Runtime | ErrorComp 使用此字段确定抛出哪种类型的异常。 |
faultType | bo string | 此字段指示错误组件的哪种类型(简单字符串或 BO)用于 ServiceBusinessException 构造器 |
实现
InvocationPatternComp 通过使用组件测试填充的 start 操作接收 ErrorBO。组件将从 BO 读取值,并在必要时进行调用。ErrorComp 然后从 InvocationPatternComp 接收 ErrorBO,读取指定要抛出的异常类型的值,并进行适当的操作。
练习示例的组件测试
启动服务器和部署模块。
右键单击 InvocationPatternComp,并选择 Test Component。
填充 BO(如下所示),并单击 Continue。
图 15. 错误测试
InvocationPatternComp 通过使用上面的值充当客户端,并使用同步调用模式通过请求/响应操作来调用 ErrorComp。ErrorComp 充当服务提供程序,并以使用业务对象 (FaultBO) 构造的 ServiceBusinessException 进行响应。
结束语
本文介绍了 WebSphere Process Server 和 WebSphere Enterprise Service Bus 中使用的异常基本类别。阐述了如何处理各种异常、如何配置重试以及在何处查找失败的消息。本文还阐述了如何确定内部使用了哪种调用机制,因为调用机制会影响处理异常的方式。
本文示例源代码或素材下载
编缉推荐阅读以下文章
- WebSphere ESB 入门:创建 POJO 并将其作为服务发布
- 改进 WebSphere ESB V6.1 中记录的消息的显示
- ››WebSphere 反向投资者: 解决 WebSphere Applicati...
- ››WebSphere sMash 的创新应用,第 2 部分: 借助包装...
- ››WPS 2009高级查找替换插件的应用
- ››WPS 2009自动填充规则技巧总结
- ››Websphere MQ v6集群的负载均衡新功能
- ››WebSphere Process Server V6.0.2 集群,第 2 部分...
- ››WebSphere Process Server V6.0.2 集群,第 1 部分...
- ››WebSphere MQ性能调优浅谈
- ››WebSphere配置资源库管理
- ››WebSphere中的SSL/TLS:用法、配置和性能
- ››websphere ejb远程/本地调用总结
- ››WebSphere Application Server对SIP的支持
更多精彩
赞助商链接