检测并结束 JavaScript 活动中的无限循环
在 IBM® Business Process Manager 应用程序中运行的 JavaScript 和 Java 代码中可能发生无限循环。您可以在 100Custom.xml 文件中配置循环检测参数来检测无限循环并可选择结束它们。
当在 IBM BPM 应用程序内运行的 JavaScript 代码中出现无限循环时,这会影响其他资源。例如,Process Center 或 Process Server 线程将丢失直至服务器停止,这会影响服务器可用性。要检测无限循环,IBM BPM 监控每个脚本活动中执行的 JavaScript 指令数。其设置指令阈值和超时以检查脚本活动的持续时间。在到达指令阈值时,JavaScript 引擎调用 IBM BPM 提供的回调,其检查脚本持续时间是否超过配置的超时。如果超出超时,那么 IBM BPM 根据配置显示 loop-detection-exception 或记录错误消息。指令阈值的缺省值为 2500 万条 JavaScript 指令。
注:
- 调用 Java 方法或 IBM BPM JavaScript API 调用(如 tw.system.executeServiceByName)记作一条指令。
- 由服务器端组件引用的受管服务器端文件内的 JavaScript 代码记作个别指令,而不仅是一条指令。
使用以下循环检测参数,您可以配置 IBM BPM 提供回调的超时和指令阈值。如果脚本持续时间超过超时,您可以选择停止脚本。
- loop-detection-duration:如果超过 loop-detection-duration 参数指定的超时值,那么假定活动处于无限循环中。缺省持续时间设置为 20 秒,但可进行配置(请参阅以下示例)。
- loop-detection-exception:缺省情况下,检测到无限循环时,IBM BPM 引擎会向 SystemOut.log 文件中写入一条警告,但脚本活动会继续运行。要将 IBM BPM 引擎配置为停止无限循环的脚本活动,请将 loop-detection-exception 参数设置为 true。如果 loop-detection-exception 参数设置为 false,那么会向 SystemOut.log 文件中写入以下某条消息:
- CWLLG2261W: {0} 秒后在“未知”活动中怀疑存在无限循环。如果此脚本未循环,请增加 loop-detection-duration 属性。
- CWLLG2263W: BPD“{2}”脚本活动“{3}”{0} 秒后在“{1}”中怀疑存在无限循环。如果此脚本未循环,请增加 loop-detection-duration 属性。
- CWLLG2265W: {0} 秒后在服务“{1}”中怀疑存在无限循环。如果此服务未循环,请增加 loop-detection-duration 属性
如果 loop-detection-exception 参数设置为 true,那么会向 SystemOut.log 文件中写入以下某条消息:- CWLLG2262E: 终止“未知”活动 {0} 秒后检测到无限循环。如果此脚本未循环,请增加 loop-detection-duration 属性。
- CWLLG2264E: 终止 BPD“{2}”脚本活动“{3}”{0} 秒后,在“{1}”中检测到无限循环。如果此脚本未循环,请增加 loop-detection-duration 属性。
- CWLLG2266E: 终止服务“{1}”{0} 秒后检测到无限循环。如果此服务未循环,请增加 loop-detection-duration 属性。
- instruction-threshold:在 JavaScript 代码在循环中进行 Java 调用并且大部分执行时间用于 Java 代码时,检测无限循环所用时间可能超过最佳时间。2500 万条 JavaScript 指令的缺省阈值所用时间可能远远超过配置的超时,并且脚本可能仍然长时间连续运行。
例如,JAR 文件代码路径中的循环可能阻止其返回到 IBM BPM 引擎以进行处理,这会延长 JavaScript 活动的持续时间。您可以使用 instruction-threshold 属性以在先前的循环检测的回调调用之间指定较小数量的 JavaScript 指令。
IBM BPM 在指示 JavaScript 引擎调用循环检测回调之前,会将配置的值乘以 100。缺省值为 250。这意味着 JavaScript 引擎每 25000 条 JavaScript 指令调用一次 IBM BPM 循环检测回调。
以下示例说明如何在 100Custom.xml 文件中配置 JavaScript 循环检测参数:
<common merge="mergeChildren">
<javascript-engine>
<loop-detection-duration merge="replace">90</loop-detection-duration>
<loop-detection-exception merge="replace">true</loop-detection-exception>
<instruction-threshold merge="replace">250</instruction-threshold>
</javascript-engine>
</common>