搞定 Oracle BPM 超时有关问题 - Solving Oracle BPM Timeout Error

搞定 Oracle BPM 超时问题 - Solving Oracle BPM Timeout Error.

Timeout 概述

如果你使用 Oracle BPM的话,可能会碰到BPEL 实例 (BPEL Instance) 因为各种原因导致的超时错误(Timeout Error)。

超时错误在BPEL 实例无法在指定时间内完成任务的时候发生。应用服务器或者BPEL 引擎都有超时参数设置来阻止长时间运行的BPEL 实例 一直占有资源。一旦运行时间超过超时参数设定的值,BPEL 实例就会收到错误信息并释放所有占有的资源。关于超时时间的设定要根据实际情况来决定。在某些环境中可能需要较长的时间,例如,如果部署在应用服务器上的绝大部分BPEL 过程(BPEL Process)依赖远程Web Service访问、这个访问本身如果很慢,而且我们无法干预的话,那么我们可能需要为这个应用服务器设置一个合理的超时参数值。 如果,你的应用更倾向于快速响应、高吞吐量的话,那么这个超时参数值就不能设置的过高,这样如果远程连接一旦失败,应用可以快速做出响应。有时候,我们可能需要将应用服务器的超时时间设置的比较高,以此来支持比较耗时的进程。同时,我们可能需要在BPEL 引擎 (BPEL Engine)或者特定的BPEL 过程 上设定较小的超时时间。Oracle BPEL Process Manager 和应用服务器 允许我们在不同的级别上设定超时时间。

这篇文章摘主要围绕BPEL 11g 版本对超时设定进行一些介绍。整片文章围绕BPEL展开,但对于使用BPMN完成的BPM 过程,同样适用。

对于超时错误,这里通常有三种类型的参数。他们包括了大部分的超时错误。对不同级别的超时参数进行正确设定,能解决大部分的超时错误。

  • 应用服务器级别
  • EJB级别
  • BPEL Engine/client 级别

BPEL Engine/client 

SyncMaxWaitTime 这个参数主要设定Client 等待一个同步调用返回所需要的最大时间。在BPEL 11g中,在如下位置进行设定。

Enterprise Manager > soa-infra > SOA Administration > BPEL Properties > More BPEL Configuration Properties > syncMaxWaitTime

这个参数适用于同步过程调用,这个过程必须是持久过程(Durable process,相对应的还有瞬时过程 transient process)。在了解什么是持久过程之前,我们要知道断点活动(Breakpoint activity).一个断点活动 告诉Oracle BPEL 引擎必须等待一个计时器过期或者等待一个消息。当BPEL 实例遇到一个断点活动时,BPEL 过程的状态会被保存到数据库里 (Oracle通常称之为dehydration) 。断点活动包括如下具体活动 

  • Receive 活动(Process的首个Receive活动除外)
  • Wait 活动
  • Pick 活动

持久过程就是有一个或多个断点活动的BPEL过程,持久过程一般存活时间较长。他们必须等待某些事件的发生或者等待某些时间直至过期。


EJB

如果你注意到支持BPM在Weblogic 上运行的 SOA_INFRA应用的话,问题较容易很多。这个应用和我们部署的其他Web应用是类似的。在SOA_INFRA应用中部署了很多的EJB,这些EJB对于支持BPM在分布式环境中运行至关重要。

我们这里提到的Timeout 参数,在EJB Level 需要对相应的EJB参数进行设置。在 BPEL 11g中,对应位置如下

Oracle WebLogic Administration Console > Deployments > soa-infra > EJBs > <Bean_name> > Transaction Timeout

所有BPEL开头的Bean 都需要做相应的修改。具体名字如下

  • BPELActivityManagerBean
  • BPELDeliveryBean
  • BPELDispatcherBean
  • BPELEngineBean
  • BPELFinderBean
  • BPELInstanceManagerBean
  • BPELProcessManagerBean
  • BPELSensorValuesBean
  • BPELServerManagerBean

如果你想对 BPMN对应的EJB 进行修改,同理以BPMN开头的Bean都需要进行修改。

应用服务器

这个参数对处于Active的事务进行事务超时设定,影响所有Web logic 域中的Active事务。如果某个事务处于Active状态超过这个时间,那么会自动回滚。

进行设定的位置如下

 WebLogic Administration Console > Services > JTA > Timeout Seconds 
 或
 WebLogic Administration Console > domain_name > JTA > Timeout Seconds

如何设定Timeout

正确的超时参数设定取决于你的环境和具体需求。每个安装环境之间不一定完全照搬。有一些建议,在进行超时参数设定时,Oracle 建议大家考虑

syncMaxWaitTime < BPEL EJB's transaction timeout < Global Transaction Timeout

这个关系更适用于同步过程。对于不是同步过程的情况,我们可能不用太考虑syncMaxWaitTime这个参数。


如何防止Timeout


  • 根据环境和需求的实际情况设定Timeout超时参数

  • 考虑将长时间运行的同步过程改为异步过程

  • 如果可能,使用One-way的异步Web service 调用

  • 捕捉timeout异常并在你的BPEL过程中做相应的处理


如何诊断Timeout


一般情况下,如果一个BPEL 实例返回了一个timeout 错误,它可能会 意味着

  1. 在BPEL过程中访问的某些/个活动花了比预期长的处理时间,或者干脆由于网络链接问题、高负载导致的性能瓶颈问题、数据库崩溃、Web service无法访问等导致程序中断
  2. 某个/些 Timeout参数设定的值过小

在上面两种情况下,我们应首先检查BPEL实例返回的错误信息,从而决定是哪一个活动执行失败,这很容易通过查看BPEL实例的工作流图来发现出问题的活动是哪一个。一旦确定了收到Timeout错误的活动,我们就能进一步找到这个活动所访问的服务具体是什么。

在第一种情况下,如果是一个外部的服务导致了超时,我们要看是否这个服务被意外中断了,具体原因是什么。或者,是否这个外部服务仅仅是花费了比预期更长的时间。如果超时错误时因为被访问的服务响应很慢所致,我们可以考虑增加Timeout 参数设定的值或者考虑将同步的BPEL 过程更新成异步的。对于同步的BPEL过程,增加 SyncMaxWaitTime的值可能是比较快的解决方案,但可能不是最好的。一般讲同步过程改为异步过程往往会更好些。

在第二种情况下,如果你看到很多由于超时错误导致失败的BPEL实例,而且也没有BPEL实例依赖的外部服务执行失败,我们就需要考虑增加BPEL Engine和应用服务器的Timeout设定了。

为了更好的定位超时错误发生的具体原因,我们可以将Logging的级别设定为 TRACE:32(FINEST).


Enterprise Manager > SOA Infrastructure > Logs > Log Configuration
oracle.soa.bpel.engine.delivery to TRACE:32 (FINEST)

按照上述设定后,Timeout异常会被写入到domain.log 和SOA Server的 diagnostic.log里

首先要看的是,是否错误的消息里包含一个时间超时提示。例如

Transaction timed out after 3601 seconds

这个消息可以帮助我们大致定位到是超过了哪个参数的设定值,这个例子里可能是与一个超时设定为3600的参数相关。

如果错误信息中不包含上述的信息,我们可以到EM Console里查看失败的BPEL 实例的Audit trail,可能会是一个Invoke活动(也可能不是,以下按照Invoke活动来展开的),通过查看这个Invoke花了多长时间,我们可以大致估算出Timeout参数的设定。

[2011/07/19 16:27:37] Updated variable "Invoke_WaitFiveMinutes_process_InputVariable"
[2011/07/19 16:28:22] Faulted while invoking operation "process" on provider "WaitFiveMinutes"

在上述例子里,Invoke活动之后,一个变量被更新了。这个Invoke花费了45秒,正是SyncMaxWaitTime的默认值。