Durable Functions 中的資料持續性和序列化 (Azure Functions)

為提供可靠的執行,Durable Functions 執行階段會自動將函式參數、傳回值和其他狀態保存至工作中樞。 但保存至耐久性儲存體的資料數量和頻率,可能影響應用程式效能和儲存體交易成本。 根據應用程式存放區的資料類型,可能也需考慮資料保留和隱私權原則。

工作中樞內容

工作中樞會儲存執行個體的目前狀態和任何擱置的訊息:

  • 執行個體狀態會儲存執行個體的目前狀態和歷程記錄。 針對協調流程執行個體,此狀態包含執行階段狀態、協調流程歷程記錄、輸入、輸出和自訂狀態。 針對實體執行個體,此會包含實體狀態。
  • 訊息會儲存函式輸入或輸出、事件承載,以及用於內部用途 (路由和端對端關聯) 的中繼資料。

訊息會在處理之後刪除,但除非應用程式或操作員明確刪除訊息,否則仍會保存執行個體狀態。 特別針對協調流程歷程記錄,即使協調流程完成之後也會保留在儲存體中。

如需狀態和訊息如何代表協調流程進度的範例,請參閱工作中樞執行範例

儲存體中狀態和訊息顯示的位置和方式都取決於儲存體提供者。 Durable Functions 的預設提供者是 Azure 儲存體,會將指定 Azure 儲存體帳戶中的資料保存至佇列、資料表和 Blob。

序列化和保存的資料類型

下列清單顯示使用 Durable Functions 功能時序列化並保存的不同資料類型:

  • 協調器、活動和實體函式的所有輸入和輸出,包括任何識別碼和未處理的例外狀況
  • 協調器、活動和實體函式名稱
  • 外部事件名稱和承載
  • 自訂協調流程狀態承載
  • 協調流程終止訊息
  • 耐久性計時器承載
  • 耐久性 HTTP 要求與回應 URL、標頭和承載
  • 實體呼叫和訊號承載
  • 實體狀態承載

搭配敏感性資料使用

使用 Azure 儲存體提供者時,所有資料都會在待用時自動加密。 但有儲存體帳戶存取權時,任何使用者都可以未加密的格式讀取資料。 如果您需要更強大的敏感資料保護,請考慮先使用您自己的加密金鑰加密資料,然後資料會以預先加密的格式保存。

或者,.NET 使用者可以選擇實作提供自動加密的自訂序列化提供者。 您可以在此 GitHub 範例中,找到使用加密的自訂序列化範例。

注意

如果您決定實作應用程式層級加密,請注意協調流程和實體可能無限期存在。 這在輪替加密金鑰時很重要,因為協調流程或實體的執行時間可能比金鑰輪替原則久。 如果發生金鑰輪替,下次執行協調流程或實體時,加密資料使用的金鑰可能無法再用於解密。 因此,只有預期在相對短時間執行協調流程和實體時,才建議使用客戶加密。

自訂序列化和還原序列化

預設序列化邏輯

適用於 .NET 的 Durable Functions 會在內部使用 Json.NET,將協調流程和實體資料序列化為 JSON。 使用的預設 Json.NET 設定如下:

輸入、輸出和狀態:

JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.None,
    DateParseHandling = DateParseHandling.None,
}

例外狀況:

JsonSerializerSettings
{
    ContractResolver = new ExceptionResolver(),
    TypeNameHandling = TypeNameHandling.Objects,
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
}

請在這裡參閱 JsonSerializerSettings 的詳細文件。

使用 .NET 屬性自訂序列化

在序列化時,Json.NET 會在類別和屬性上,尋找控制資料從 JSON 序列化和還原序列化資料的各種屬性。 如果您有資料類型傳遞至 Durable Functions API 後的原始程式碼,請考慮新增這些屬性至類型,並自訂序列化和還原序列化。

使用相依性插入自訂序列化

以 .NET 為目標並在 Functions V3 執行階段上執行的函式應用程式,可以使用相依性插入 (DI) 自訂資料和例外狀況的序列化方式。 下列範例程式碼示範使用 IMessageSerializerSettingsFactoryIErrorSerializerSettingsFactory 服務介面的自訂實作時,如何使用 DI 覆寫預設 Json.NET 序列化設定。

using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Azure.WebJobs.Extensions.DurableTask;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using System.Collections.Generic;

[assembly: FunctionsStartup(typeof(MyApplication.Startup))]
namespace MyApplication
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(IFunctionsHostBuilder builder)
        {
            builder.Services.AddSingleton<IMessageSerializerSettingsFactory, CustomMessageSerializerSettingsFactory>();
            builder.Services.AddSingleton<IErrorSerializerSettingsFactory, CustomErrorSerializerSettingsFactory>();
        }

        /// <summary>
        /// A factory that provides the serialization for all inputs and outputs for activities and
        /// orchestrations, as well as entity state.
        /// </summary>
        internal class CustomMessageSerializerSettingsFactory : IMessageSerializerSettingsFactory
        {
            public JsonSerializerSettings CreateJsonSerializerSettings()
            {
                // Return your custom JsonSerializerSettings here
            }
        }

        /// <summary>
        /// A factory that provides the serialization for all exceptions thrown by activities
        /// and orchestrations
        /// </summary>
        internal class CustomErrorSerializerSettingsFactory : IErrorSerializerSettingsFactory
        {
            public JsonSerializerSettings CreateJsonSerializerSettings()
            {
                // Return your custom JsonSerializerSettings here
            }
        }
    }
}