优化业务规则引擎 (BRE) 性能
在BizTalk Server解决方案中实现业务规则引擎 (BRE) 时,应考虑以下因素:
事实类型
与访问 XML 和数据库事实所需的时间相比,规则引擎访问 .NET 事实所需的时间更少。 如果选择在策略中使用 .NET 或 XML 或数据库事实,应考虑使用 .NET 事实来提高性能。
数据表与数据连接
当数据集的大小较小 (< 10) 左右时, TypedDataTable 绑定提供的性能优于 DataConnection 绑定。 但是,当数据集较大 (大约) 大于或等于 10 行时, DataConnection 绑定的性能优于 TypedDataTable 绑定。 因此,应根据数据集的估计大小决定是使用 DataConnection 绑定还是 TypedDataTable 绑定。
事实检索器
事实检索器实现标准方法,这些方法通常用于在执行策略之前向规则引擎提供长期且缓慢变化的事实。 引擎将缓存这些事实,并在多个执行循环中使用它们。 不应在每次调用规则引擎时都提交静态或相当静态的事实,而应创建首次提交事实的事实检索器,然后仅在必要时更新内存中的事实。
规则优先级
规则的优先级设置范围可以是 0 的任一端,数字越大,优先级越高。 操作按从最高优先级到最低优先级的顺序执行。 当策略使用 断言/更新 调用实现前向链接行为时,可以使用优先级设置优化链接。 例如,假设 Rule2 依赖于 Rule1 设置的值。 赋予 Rule1 更高的优先级意味着 Rule2 仅在 Rule1 触发并更新值后才会执行。 相反,如果 为 Rule2 指定了更高的优先级,它可以触发一次,然后在 Rule1 触发后再次触发,并更新 Rule2 正在使用条件的事实。 虽然这可以提供正确的结果,但在此方案中为 Rule1 提供更高的优先级将提供更好的性能。
更新调用
Update 函数会导致使用更新的事实的所有规则重新计算。 更新函数调用可能非常昂贵,尤其是在更新事实时重新计算大量规则时。 在某些情况下,可以避免此行为。 例如,请考虑以下规则。
规则 1:
IF PurchaseOrder.Amount > 5
THEN StatusObj.Flag = true; Update(StatusObj)
规则 2:
IF PurchaseOrder.Amount <= 5
THEN StatusObj.Flag = false; Update(StatusObj)
策略的所有剩余规则在其条件中使用 StatusObj.Flag 。 因此,当对 StatusObj 对象调用 Update 时,将重新计算所有规则。 无论 Amount 字段的值是什么,除 Rule1 或 Rule2 之外的所有规则都会评估两次,一次是在 Update 调用之前计算一次,在 Update 调用之后计算一次。
若要缓解关联的开销,可以在调用策略之前将 标志 字段的值设置为 false ,然后在策略中仅使用 Rule1 来设置标志。 在这种情况下,仅当 Amount 字段的值大于 5 时,才会调用 Update;如果 Amount 的值小于或等于 5,则不调用 Update 函数。 因此,仅当 Amount 字段的值大于 5 时,才计算除 Rule1 或 Rule2 之外的所有规则两次。
逻辑 OR 运算符的使用
如果在条件中越来越多地使用“逻辑或”运算符,会进行额外的排列,从而扩展规则引擎的分析网络。 从性能角度来看,最好将条件拆分为不包含“逻辑或”运算符的原子规则。
缓存设置
规则引擎使用两个缓存。 第一个由更新服务使用,第二个由每个 BizTalk 进程使用。 首次使用策略时,BizTalk 进程会从更新服务请求策略信息。 更新服务从规则引擎数据库中检索策略信息,将其缓存,并将信息返回到 BizTalk 进程。 BizTalk 进程基于该信息创建策略对象,并在关联的规则引擎实例完成策略执行时将策略对象存储在缓存中。 再次调用同一策略时,BizTalk 进程会重复使用缓存中的策略对象(如果有)。 同样,如果 BizTalk 进程从更新服务请求有关策略的信息,则更新服务会在其缓存中查找策略信息(如果可用)。 每隔 60 秒,更新服务还会检查数据库中的策略是否有任何更新。 如果有任何更新,更新服务将检索信息并缓存更新的信息。
规则引擎有三个与这些缓存相关的优化参数: CacheEntries、 CacheTimeout 和 PollingInterval。 您可以在注册表或配置文件中为这些参数指定值。 CacheEntries 参数的值是缓存中的最大条目数,默认情况下设置为值 32。 你可能希望增加 CacheEntries 参数的值,以提高在某些情况下的性能。 例如,假设重复使用 40 个策略;可以将 CacheEntries 参数的值增加到 40 以提高性能。 这将允许更新服务在内存中维护最多 40 个策略的缓存详细信息。
CacheTimeout 的值是条目在更新服务缓存中维护的时间(以秒为单位)。 换句话说, CacheTimeout 值是指策略的缓存项在缓存中保留多长时间,而不进行引用。 CacheTimeout 参数的默认值为 3600 秒或 1 小时。 这意味着,如果未在一小时内引用缓存项,则会删除该条目。 在某些情况下,增加 CacheTimeout 参数的值以提高性能可能很有用。 例如,如果每两小时调用一次策略,则会通过将 CacheTimeout 参数增加到大于两小时的值来提高策略执行的性能。
规则引擎的 PollingInterval 参数定义更新服务检查规则引擎数据库进行更新的时间(以秒为单位)。 PollingInterval 参数的默认值为 60 秒。 如果知道策略根本没有更新或很少更新,则可以将此参数更改为更高的值以提高性能。
SideEffects 属性
ClassMemberBinding、DatabaseColumnBinding 和 XmlDocumentFieldBinding 类具有名为 SideEffects 的属性。 此属性确定是否缓存绑定字段的值、成员或列。 DatabaseColumnBinding 和 XmlDocumentFieldBinding 类中的 SideEffects 属性的默认值为 false。 ClassMemberBinding 类中 SideEffects 属性的默认值为 true。 因此,如果 XML 文档字段或数据库表的列是在策略中第二次访问或稍后访问的,则其值从缓存中检索。 不过,如果 .NET 对象的成员是第二次访问或稍后访问的,其值从 .NET 对象检索,而不是从缓存中检索。 将 .NET ClassMemberBinding 的 SideEffects 属性设置为 false 将提高性能,因为将从第二次开始从缓存中检索字段的值。 您只能通过编程方式来完成此步骤。 业务规则编辑器工具不公开 SideEffects 属性。
实例和选择性
XmlDocumentBinding、ClassBinding 和 DatabaseBinding 类有两个属性:Instances 和 Selectivity。 Instances 的值是工作内存中类的实例的预期数目。 Selectivity 的值是成功通过规则条件的类实例的百分比。 规则引擎使用这些值来优化条件计算,这样在条件计算中最初尽可能使用最少的实例,以后再使用其余的实例。 如果事先知道对象的实例数,将 Instances 属性设置为该值将提高性能。 同样,如果事先知道这些对象传递条件的百分比,将 Selectivity 属性设置为该值可以提高性能。 只能通过编程方式来设置这些参数的值。 业务规则编辑器工具不公开这些属性。