本文件涵蓋工作流程設計和設定與工作流程持續性相關的最佳做法。
長期工作流程的設計與實作
一般而言,工作流程會在短時間內執行任務,然後在等待事件時處於閒置狀態。 此事件可以是訊息或即將過期的計時器。 若要能夠在工作流程實例閑置時卸除工作流程實例,服務主機必須保存工作流程實例。 只有當工作流程實例不在無持久化區域中時,此操作才有可能(例如,等候交易完成,或等候異步回呼)。 若要允許閑置的工作流程實例卸除,工作流程作者應該只針對短期動作使用交易範圍和異步活動。 特別是,作者應儘可能縮短這些無持久性區域中的延遲活動。
只有在工作流程使用的所有數據類型都可串行化時,才能保存工作流程。 此外,使用於持久性工作流程的自定義類型必須可 NetDataContractSerializer 串行化,以便由 SqlWorkflowInstanceStore 保存。
如未持久化,當主機或計算機發生故障時,工作流程實例將無法復原。 一般而言,我們建議您在工作流程的生命週期初期保存流程實例。
如果您的流程長時間處於忙碌狀態,我們建議您在整個忙碌期間持續保存流程實例。 您可以透過在整個活動序列中新增 Persist 活動,使工作流程實例維持忙碌來達成此目的。 如此一來,應用程式域重啟、主機故障或電腦故障不會使系統回到忙碌期間的開始。 請注意,將活動新增 Persist 至您的工作流程可能會導致效能降低。
Windows Server App Fabric 可大幅簡化設定和使用持續性。 如需詳細資訊,請參閱 Windows Server App Fabric 資料持久性
設定延展性參數
延展性和效能需求會決定下列參數的設定:
根據目前的案例,這些參數應該如下所示設定。
案例:需要最佳回應時間的少數工作流程實例
在此案例中,所有工作流程實例在閑置時都應該保持載入狀態。 設定 TimeToUnload 為大型值。 使用此設定可防止工作流程實例在計算機之間移動。 只有在下列一或多個為 true 時,才使用此設定:
工作流程實例在其存留期內會收到單一訊息。
所有工作流程實例都會在單一計算機上執行
工作流程實例所接收的所有訊息都會由同一部電腦接收。
使用 Persist 活動或設定 TimeToPersist 為 0,以在服務主機或電腦失敗之後啟用工作流程實例的復原。
案例:工作流程實例長時間閑置
在此案例中,設定 TimeToUnload 為0以儘快釋放資源。
案例:工作流程實例在短時間內接收多個訊息
在此案例中,如果相同計算機收到這些訊息,請將 設定 TimeToUnload 為 60 秒。 這可防止頻繁卸除和載入工作流程實例。 這也不會讓實例保留在記憶體中太久。
設定 TimeToUnload 為 0,如果不同電腦可能會收到這些訊息,則設定 InstanceLockedExceptionAction 為 BasicRetry 或 AggressiveRetry。 這可讓另一部計算機載入工作流程實例。
案例:工作流程使用持續時間較短的延遲活動
在此案例中, SqlWorkflowInstanceStore 會定期從持久性資料庫中搜尋,尋找因活動 Delay 過期而需要載入的實例。 如果SqlWorkflowInstanceStore在下一個輪詢間隔內找到將到期的定時器,則 SQL 工作流程實例存放區會縮短輪詢間隔。 下一次輪詢會在定時器過期後立即進行。 如此一來,SQL 工作流程實例存放區對於運行時間超過輪詢間隔的定時器達到了高精確度,而此間隔是由 RunnableInstancesDetectionPeriod 設定的。 若要啟用較短延遲的即時處理,工作流程實例必須在記憶體中至少維持一個輪詢間隔。
設定 TimeToPersist 為 0,將到期時間寫入持續性資料庫。
將 設定 TimeToUnload 為大於或等於 RunnableInstancesDetectionPeriod ,以將實例保留在記憶體中至少一個輪詢間隔。
不建議減少 , RunnableInstancesDetectionPeriod 因為這會導致持續性資料庫的負載增加。 每個使用 SqlWorkflowInstanceStore 的服務主機在每個檢測期間會對資料庫輪詢一次。 如果服務主機的數量很大,將 RunnableInstancesDetectionPeriod 設定為過小的時間間隔,可能會導致系統效能下降。
設定 SQL 工作流程實例存放區
SQL 工作流程實例存放區具有下列組態參數:
InstanceEncodingOption
此參數會指示 SqlWorkflowInstanceStore 壓縮工作流程實例的狀態。 壓縮可減少儲存在持續性資料庫中的數據量,並在持續性資料庫位於專用資料庫伺服器時減少網路流量。 如果使用壓縮,則需要計算資源來壓縮和擷取實例狀態。 在大部分情況下,壓縮會產生更高的效能。
InstanceCompletionAction
此參數指示 SqlWorkflowInstanceStore 保留或刪除已完成的實例。 保留已完成的實例會增加持續性資料庫記憶體需求,並導致較大的數據表,這會增加數據表查閱時間。 除非偵錯或稽核需要已完成的實例,否則最好指示 SqlWorkflowInstanceStore 刪除已完成的實例。 只有當使用者建立程式以最終移除它們時,才應保留已刪除的實例。 請注意,只要已完成的工作流程實例位於實例存放區中,就無法重複使用相互關聯索引鍵。
RunnableInstancesDetectionPeriod
此參數定義了SqlWorkflowInstanceStore輪詢持續性資料庫以載入需在Delay活動到期時載入的實例的最大間隔。
SqlWorkflowInstanceStore如果 找到將在下一個輪詢間隔中到期的定時器,則會縮短輪詢間隔,讓下一次輪詢會在定時器過期之後進行。 如此一來,SQL 工作流程實例存放區將對於運行超過 RunnableInstancesDetectionPeriod 的定時器達到高度的準確性。
我們不建議減少 RunnableInstancesDetectionPeriod,因為這會導致持續性資料庫的負載增加。 每個使用 SqlWorkflowInstanceStore 的服務主機在每個檢測期間會對資料庫輪詢一次。 如果服務主機數目很大,將 RunnableInstancesDetectionPeriod 設定為過小,可能會導致系統效能下降。
HostLockRenewalPeriod
此參數會定義主機在持續性資料庫中更新其鎖定的間隔。 縮短此間隔可讓工作流程實例在主機或計算機失敗時更快速地復原。 另一方面,短暫的鎖定更新期間會增加持續性資料庫的負載。 每個使用 SqlWorkflowInstanceStore 的服務主機都會在每次續約期間更新一次資料庫中的鎖定。 如果電腦執行許多服務主機,請確定鎖定更新所造成的負載不會降低系統的效能。 如果這樣做,請考慮增加 HostLockRenewalPeriod。
InstanceLockedExceptionAction
如果已啟用,則會 SqlWorkflowInstanceStore 重試以在未來 30 秒內載入鎖定的實例。 如果工作流程在短時間內收到多個訊息,且這些訊息是由不同的電腦接收,則設定 InstanceLockedExceptionAction 為 BasicRetry 或 AggressiveRetry。
因為只要未嘗試負載重試,載入重試機制就不會造成效能上的任何額外負荷,因此 InstanceLockedExceptionAction 應該一律啟用。