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) 自訂資料和例外狀況的序列化方式。 下列範例程式碼示範使用 IMessageSerializerSettingsFactory
和 IErrorSerializerSettingsFactory
服務介面的自訂實作時,如何使用 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
}
}
}
}