共用方式為


Durable Functions 疑難解答指南

Durable Functions 是 Azure Functions 的延伸模組,可讓您使用一般程式代碼建置無伺服器協調流程。 如需 Durable Functions 的詳細資訊,請參閱 Durable Functions 概觀

本文提供針對 Durable Functions 應用程式中常見案例進行疑難解答的指南。

備註

Microsoft支援工程師可用來協助診斷應用程式的問題。 如果您無法使用本指南診斷您的問題,可以在 Azure 入口網站中透過您函數應用程式的 [支援 + 疑難排解] 區段,存取 [新的支援要求] 刀鋒視窗以提交支援要求。

Azure 入口網站中支援要求頁面的螢幕快照。

小提示

偵錯和診斷問題時,建議您從確保應用程式使用最新的 Durable Functions 擴充功能版本開始。 大部分時候,使用最新版本可減輕其他使用者已回報的已知問題。 如需如何升級延伸模組版本的指示,請參閱 升級 Durable Functions 擴充功能版本 一文。

Azure 入口網站中的 [ 診斷和解決問題 ] 索引標籤是用來監視和診斷與您應用程式相關的可能問題的資源。 它也會根據診斷,為您的問題提供潛在的解決方案。 如需詳細資訊,請參閱 Azure 函式應用程式診斷

如果上述資源無法解決問題,下列各節會提供特定應用程式徵兆的建議:

協調流程停滯在 Pending 狀態

當您啟動協調流程時,會將「開始」訊息寫入長期擴充功能所管理的內部佇列,而協調流程的狀態會設定為「擱置」。 當協調流程訊息由可用的應用程式實例挑選並成功處理之後,狀態會轉換為「執行中」(或某些其他非「擱置」狀態)。

使用下列步驟,針對無限期停滯在「擱置」狀態的協調流程實例進行疑難解答。

  • 請檢查 Durable Task Framework 追蹤記錄中是否有與受影響的協調實例 ID 相關的警告或錯誤。 您可以在 追蹤錯誤/警告一節中找到範例查詢。

  • 請檢查指派給停滯協調器的 Azure 記憶體控制佇列,以查看其「開始訊息」是否仍然存在。如需控制佇列的詳細資訊,請參閱 Azure 記憶體提供者控制佇列檔

  • 將應用程式的 平台組態 版本變更為 「64 位」。。 有時候協調流程不會啟動,因為應用程式記憶體不足。 切換至64位進程可讓應用程式配置更多總記憶體。 這隻適用於 App Service Basic、Standard、Premium 和 Elastic Premium 方案。 免費或使用量方案支援 64 位元流程。

協調流程會在長時間延遲之後啟動

一般而言,協調流程會在排程後的幾秒內啟動。 不過,在某些情況下,協調流程可能需要較長的時間才能啟動。 使用下列步驟,在協調流程需要幾秒鐘以上的時間才能開始執行時進行疑難排解。

協調流程未完成/停滯於 Running 狀態

如果協調流程長時間維持在「執行中」狀態,通常表示它正在等候已排定的長時間執行工作完成。 例如,它可能正在等待持久計時器工作、活動工作或外部事件工作完成。 不過,如果您觀察到排程的工作已順利完成,但協調流程卻仍然沒有任何進展,則可能發生問題,導致協調流程無法繼續下一項工作。 我們通常會將此狀態中的協調流程稱為「停滯的協調流程」。

請使用下列步驟對停滯的協調流程進行疑難排解:

  • 請嘗試重新啟動函式應用程式。 此步驟可協助協調流程因應用程式或擴充程式代碼中的暫時性錯誤或死結而停滯。

  • 檢查 Azure 記憶體帳戶控制佇列,以查看是否有任何佇列持續成長。 這個 Azure 儲存體傳訊 KQL 查詢可協助找出清除協調流程佇列訊息的問題。 如果問題只影響單一控制佇列,這可能表示只存在於特定應用程式實例上的問題。在這種情況下,擴展或縮減應用程式實例以移開不良的 VM 實例可能會有所幫助。

  • 使用 Azure 記憶體傳訊區段中 的 Application Insights 查詢,篩選該佇列名稱作為分割區標識碼,並尋找與該控制佇列分割相關的任何問題。

  • 檢查 Durable Functions 最佳做法和診斷工具中的指引。 某些問題可能是由已知的 Durable Functions 反模式所造成。

  • 檢查 Durable Functions 版本控制檔。 某些問題可能是因為傳輸中協調流程執行個體的中斷性變更所造成。

協調流程執行速度緩慢

大量數據處理、內部錯誤和計算資源不足可能會導致協調流程的執行速度比正常慢。 使用下列步驟,針對執行時間超過預期的協調流程進行疑難排解:

  • 請檢查「Durable Task Framework」中的追蹤紀錄,看是否有影響到的協調處理程序實例 ID 的警告或錯誤。 您可以在 追蹤錯誤/警告一節中找到範例查詢。

  • 如果您的應用程式使用 .NET 進程內模型,請考慮啟用 延伸會話。 延長會話可以將歷程記錄的載入降到最低,從而加快處理速度。

  • 檢查效能和可擴展性瓶頸。 應用程式效能取決於許多因素。 例如,高 CPU 使用量或大型記憶體耗用量可能會導致延遲。 如需詳細指引 ,請參閱 Durable Functions 中的效能和規模

範例查詢

本節說明如何在為 Azure Functions 應用程式設定的 Azure Application Insights 實例中撰寫自定義 KQL 查詢 ,以針對問題進行疑難解答。

Azure 儲存體傳訊

使用預設的 Azure 記憶體提供者時,所有 Durable Functions 行為都是由 Azure 記憶體佇列訊息所驅動,而與協調流程相關的所有狀態都會儲存在數據表記憶體和 Blob 記憶體中。 啟用長期工作架構追蹤時,所有 Azure 記憶體互動都會記錄至 Application Insights,而且這項數據對於偵錯執行和效能問題非常重要。

從 Durable Functions 延伸模組的 v2.3.0 開始,您可以透過更新 host.json 檔案中的記錄設定,將這些 Durable Task Framework 的記錄發佈到您的 Application Insights 實例。 如需有關如何執行此操作的資訊和指示,請參閱 Durable Task Framework 記錄文章

下列查詢用於檢查特定協調流程實例的端對端 Azure 記憶體互動。 編輯 startorchestrationInstanceID 以依時間範圍和實例標識碼進行篩選。

let start = datetime(XXXX-XX-XXTXX:XX:XX); // edit this 
let orchestrationInstanceID = "XXXXXXX"; //edit this
traces  
| where timestamp > start and timestamp < start + 1h 
| where customDimensions.Category == "DurableTask.AzureStorage" 
| extend taskName = customDimensions["EventName"]
| extend eventType = customDimensions["prop__EventType"] 
| extend extendedSession = customDimensions["prop__IsExtendedSession"]
| extend account = customDimensions["prop__Account"] 
| extend details = customDimensions["prop__Details"] 
| extend instanceId = customDimensions["prop__InstanceId"] 
| extend messageId = customDimensions["prop__MessageId"] 
| extend executionId = customDimensions["prop__ExecutionId"] 
| extend age = customDimensions["prop__Age"] 
| extend latencyMs = customDimensions["prop__LatencyMs"] 
| extend dequeueCount = customDimensions["prop__DequeueCount"] 
| extend partitionId = customDimensions["prop__PartitionId"] 
| extend eventCount = customDimensions["prop__TotalEventCount"] 
| extend taskHub = customDimensions["prop__TaskHub"] 
| extend pid = customDimensions["ProcessId"]
| extend appName = cloud_RoleName
| extend newEvents = customDimensions["prop__NewEvents"]
| where instanceId == orchestrationInstanceID
| sort by timestamp asc
| project timestamp, appName, severityLevel, pid, taskName, eventType, message, details, messageId, partitionId, instanceId, executionId, age, latencyMs, dequeueCount, eventCount, newEvents, taskHub, account, extendedSession, sdkVersion

追蹤錯誤/警告

下列查詢會搜尋指定協調流程執行個體的錯誤和警告。 您需要提供一個值給 orchestrationInstanceID

let orchestrationInstanceID = "XXXXXX"; // edit this
let start = datetime(XXXX-XX-XXTXX:XX:XX); 
traces  
| where timestamp > start and timestamp < start + 1h
| extend instanceId = iif(isnull(customDimensions["prop__InstanceId"] ) , customDimensions["prop__instanceId"], customDimensions["prop__InstanceId"] ) 
| extend logLevel = customDimensions["LogLevel"]
| extend functionName = customDimensions["prop__functionName"]
| extend status = customDimensions["prop__status"]
| extend details = customDimensions["prop__Details"] 
| extend reason = customDimensions["prop__reason"]
| where severityLevel >= 1 // to see all logs of severity level "Information" or greater.
| where instanceId == orchestrationInstanceID
| sort by timestamp asc 

控制佇列/分割區識別碼記錄

下列查詢會搜尋與 instanceId 控制佇列相關聯的所有活動。 您必須在 中 orchestrationInstanceID 提供 instanceID 的值,並在 中 start提供查詢的開始時間。

let orchestrationInstanceID = "XXXXXX"; // edit this
let start = datetime(XXXX-XX-XXTXX:XX:XX); // edit this
traces  // determine control queue for this orchestrator
| where timestamp > start and timestamp < start + 1h 
| extend instanceId = customDimensions["prop__TargetInstanceId"] 
| extend partitionId = tostring(customDimensions["prop__PartitionId"])
| where partitionId contains "control" 
| where instanceId == orchestrationInstanceID
| join kind = rightsemi(
traces  
| where timestamp > start and timestamp < start + 1h 
| where customDimensions.Category == "DurableTask.AzureStorage" 
| extend taskName = customDimensions["EventName"]
| extend eventType = customDimensions["prop__EventType"] 
| extend extendedSession = customDimensions["prop__IsExtendedSession"]
| extend account = customDimensions["prop__Account"] 
| extend details = customDimensions["prop__Details"] 
| extend instanceId = customDimensions["prop__InstanceId"] 
| extend messageId = customDimensions["prop__MessageId"] 
| extend executionId = customDimensions["prop__ExecutionId"] 
| extend age = customDimensions["prop__Age"] 
| extend latencyMs = customDimensions["prop__LatencyMs"] 
| extend dequeueCount = customDimensions["prop__DequeueCount"] 
| extend partitionId = tostring(customDimensions["prop__PartitionId"])
| extend eventCount = customDimensions["prop__TotalEventCount"] 
| extend taskHub = customDimensions["prop__TaskHub"] 
| extend pid = customDimensions["ProcessId"]
| extend appName = cloud_RoleName
| extend newEvents = customDimensions["prop__NewEvents"]
) on partitionId
| sort by timestamp asc
| project timestamp, appName, severityLevel, pid, taskName, eventType, message, details, messageId, partitionId, instanceId, executionId, age, latencyMs, dequeueCount, eventCount, newEvents, taskHub, account, extendedSession, sdkVersion

Application Insights 資料行參考

以下是上述查詢及其各自描述所投影的資料行清單。

資料行 說明
pid 函式應用程式實例的進程標識碼。 這對於判斷協調流程執行時是否回收處理序很有幫助。
任務名稱 要記錄的事件名稱。
事件類型 訊息的類型,這通常代表協調器完成的工作。 其可能值及其描述的完整清單 在這裡
extendedSession 布爾值,指出是否啟用 擴充會話
account 應用程式所使用的記憶體帳戶。
詳細資訊 特定事件的其他資訊,如果有的話。
instanceId 指定協調流程或實體執行個體的識別碼。
訊息ID 指定佇列訊息的唯一 Azure 記憶體識別碼。 此值最常出現在 ReceivedMessage、ProcessingMessage 和 DeletingMessage 追蹤事件中。 請注意,在 SendMessage 事件中不存在,因為我們傳送訊息 之後 ,Azure 記憶體會產生訊息標識碼。
執行識別碼 協調器執行的標識碼,每當 continue-as-new 叫用時就會變更。
年齡 訊息加入佇列後的毫秒數。 大量數位通常表示效能問題。 例外狀況是 TimerFired 訊息類型,會視計時器的持續時間而可能有較大的 Age 值。
延遲時間(毫秒) 某些記憶體作業所花費的毫秒數。
dequeueCount 訊息已從佇列清除的次數。 在正常情況下,此值一律為 1。 如果超過一個,則可能有問題。
partitionId 與此記錄相關聯的佇列名稱。
總事件數量 目前動作所涉及的歷史事件數量。
taskHub 你的 工作樞紐 的名稱。
newEvents 歷程記錄事件的逗號分隔清單,這些事件會寫入儲存體中的歷程記錄資料表。