使用規則引擎時的效能考量
本主題討論規則引擎如何在各種情況下執行,以及使用各種不同的組態/調整參數值來執行。
事實類型
規則引擎存取 .NET 事實所需的時間,少於存取 XML 和資料庫事實所需的時間。 如果您可選擇在原則中使用 .NET、XML 或資料庫事實,您應該考慮使用 .NET 事實,以取得更好的效能。
資料表與資料連接繫結的比較
當資料集的大小很小 (少於大約 10 個數據列) 時, TypedDataTable 系結的執行效能會比 DataConnection 系結更好。 當資料集很大 (大於或等於大約 10 個數據列) 時, DataConnection 系結的執行效能會優於 TypedDataTable 系結。 因此,您應該根據資料集的估計大小,決定是否要使用 DataConnection 系結或 TypedDataTable 系結。
事實擷取器
您可以撰寫事實擷取器,它是實作標準方法的物件,而且通常會在執行原則之前,使用這些方法將長期與緩慢變化的事實提供給規則引擎。 此引擎會快取這些事實,並透過多個執行循環來使用這些事實。 您應該在第一次叫用規則引擎時建立事實擷取器來提交事實,然後只有在需要時才更新記憶體中的事實,而不要在每次叫用規則引擎時都提交靜態或相當靜態的事實。
規則優先順序
規則的優先順序設定可以介於 0的任一端,且具有較高優先順序的較大數位。 會依照最高優先順序到最低優先順序的順序來執行動作。 當原則使用 Assert/Update 呼叫實作向前鏈結行為時,可以使用優先順序設定來優化鏈結。 例如,假設 Rule2 相依于 Rule1所設定的值。 為 Rule1 提供較高的優先順序表示 Rule2 只會在 Rule1 引發並更新值之後執行。 相反地,如果 Rule2 的優先順序較高,它可以引發一次,然後在 Rule1 引發之後再次引發,並更新 Rule2 在條件中使用的事實。 這樣不一定會產生正確的結果,但清楚的一點是,引發兩次與只引發一次相較之下,會有效能上的影響。
Update 呼叫
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 呼叫之前,一次是在 Update 呼叫之後。
相反地,您可以在叫用原則之前,將 旗標 欄位的值設定為 false ,然後在原則中只使用 Rule1 來設定旗標。 在此情況下,只有在Amount欄位的值大於 5 時,才會呼叫Update,如果金額小於或等於 5,則不會呼叫Update。 因此,只有在Amount欄位的值大於 5 時,才會評估Rule1和Rule2以外的所有規則兩次。
使用邏輯 OR 運算子
規則引擎已針對執行邏輯 AND 運算子進行優化,並重新建構其剖析為分離一般格式的規則,以便只使用最上層的 OR 運算子。 在條件中使用遞增的邏輯 OR 運算子會建立額外的排列,以擴充規則引擎的分析網路,而且規則引擎可能需要很長的時間才能將規則正規化。 下列清單包含這個問題的可能因應措施。
將規則修改為處於分離的一般格式,讓 OR 運算子只位於最上層。 請注意,在商務規則編輯器中以 Disjunctive Normal Form (DNF) 開發規則可能需要一些訣竅。 您可以考慮以程式設計方式建立規則。
開發執行 OR 作業並傳回布林值的協助程式元件,並在規則中使用元件。
考慮將規則分割為多個規則,讓下一個規則檢查上一個執行過的規則所設定的旗標,或使用上一個執行過的規則所判斷提示的物件,如下列範例所示:
規則 1:如果 (a == 1 OR a == 3) THEN b = true
規則 2:如果 (b == true) THEN ...
規則 1:IF (a == 1 OR a == 3) THEN assert (new c () )
規則 2:IF (c.flag == true) THEN ...
快取設定
規則引擎會使用兩個快取, 第一個是在更新服務中,第二個是在每一個 BizTalk 處理序中。 當第一次使用原則時,BizTalk 處理序會從更新服務要求原則資訊。 更新服務會從規則引擎資料庫擷取原則資訊、快取該資訊,並將該資訊傳回到 BizTalk 處理序。 BizTalk 處理序會根據該資訊來建立原則物件,並在關聯的規則引擎執行個體完成原則的執行時,將該原則物件儲存在快取中。 當再次叫用相同的原則時,如果快取中有可用的原則物件,則 BizTalk 處理序會重複使用快取中的原則物件。
同樣地,如果 BizTalk 處理序從更新服務要求與原則有關的資訊,則更新服務會先在快取中尋找原則資訊。 更新服務也會每隔 60 秒鐘 (1 分鐘) 檢查一次,看看資料庫中的原則是否有任何更新。 如果有任何更新,更新服務會擷取資訊,並快取更新的資訊。
與這些快取相關的規則引擎有三個微調參數: CacheEntries、 CacheTimeout和 PollingInterval。 您可以在登錄或組態檔中,為這些參數指定值。
CacheEntries的值是快取中的專案數上限。 CacheEntries的預設值為 32。 在某些情況下,您可能會想要增加 CacheEntries 參數的值,以改善效能。 例如,假設您重複使用 40 個原則, 在此情況下,您可能會想要將 CacheEntries 的值增加到 40,以改善效能。 如此可讓更新服務在記憶體中快取多達 40 個原則的詳細資料, 也可讓 BizTalk 服務在記憶體中快取多達 40 個原則執行個體。 在 BizTalk 服務的快取中,可能會有一個以上的原則執行個體。
CacheTimeout的值是 (秒的時間,) 讓專案離開更新服務快取。 換句話說, CacheTimeout 值是指沒有參考原則時,原則的快取專案保留在快取中的時間長度。 CacheTimeout的預設值為 3600 秒, (一小時) 。 這表示,如果在一個小時內未參考此快取項目,就會將它刪除。 在某些情況下,您可能想要增加 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 屬性設定為該值可改善效能。 您只能以程式設計方式設定這些參數的值。 「商務規則編輯器」工具不會公開這些參數。