共用方式為


協調流程版本設定 (預覽)

在使用耐用的編排系統時,升級與降級編排是關鍵考量。 若編排中斷後(例如主機更新期間)恢復,Durable Task Scheduler 會重播編排事件,確保所有先前步驟都成功執行後再進行下一步。 此舉確保可靠性,是持久執行範式的核心承諾之一。

如果編排在兩次部署間改變,所採取的步驟可能不再相同。 此時系統會拋出一個 NonDeterministicError,而非讓編排繼續。

編排版本控制 防止與非確定性相關的問題,讓你能無縫處理新舊編排。 Durable Task Scheduler 有兩種不同的版本管理方式,你可以單獨使用或合併使用:

這很重要

目前,長期工作 SDK 不適用於 JavaScript 和 PowerShell。

這很重要

目前,長期工作 SDK 不適用於 JavaScript 和 PowerShell。

用戶端/內容型條件式版本控制

要讓編排有一個版本,必須先在客戶端進行設定。

.NET SDK 使用標準的主機建構擴充套件。

備註

自 v1.9.0 起,已在 .NET SDKMicrosoft.DurableTask.Client.AzureManaged 中提供。

builder.Services.AddDurableTaskClient(builder =>
{
    builder.UseDurableTaskScheduler(connectionString);
    builder.UseDefaultVersion("1.0.0");
});

備註

自 Java SDKcom.microsoft:durabletask-client 1.6.0 起提供。

public DurableTaskClient durableTaskClient(DurableTaskProperties properties) {
    // Create client using Azure-managed extensions
    return DurableTaskSchedulerClientExtensions.createClientBuilder(properties.getConnectionString())
        .defaultVersion("1.0")
        .build();
}
 c = DurableTaskSchedulerClient(host_address=endpoint, secure_channel=secure_channel,
                                   taskhub=taskhub_name, token_credential=credential,
                                   default_version="1.0.0")

將版本新增至用戶端後,任何由此主機啟動的協調流程都會使用版本1.0.0。 該版本是一個簡單的字串,接受任意值。 然而,SDK 嘗試將其轉換為 。NET 的 System.Version.

  • 如果 轉換,該函式庫會用於比較。
  • 不合 ,則使用簡單的字串比較。

在客戶端提供版本後,也能在TaskOrchestrationContext中使用該版本,也就是說你可以在條件語句中使用該版本。 只要新版編排版本有適當的封控,舊版和新版編排版就能在同一主機上同時執行。

Example:

[DurableTask]
class HelloCities : TaskOrchestrator<string, List<string>>
{
    private readonly string[] Cities = ["Seattle", "Amsterdam", "Hyderabad", "Kuala Lumpur", "Shanghai", "Tokyo"];

    public override async Task<List<string>> RunAsync(TaskOrchestrationContext context, string input)
    {
        List<string> results = [];
        foreach (var city in Cities)
        {
            results.Add(await context.CallSayHelloAsync($"{city} v{context.Version}"));
            if (context.CompareVersionTo("2.0.0") >= 0)
            {
                results.Add(await context.CallSayGoodbyeAsync($"{city} v{context.Version}"));
            }
        }

        Console.WriteLine("HelloCities orchestration completed.");
        return results;
    }
}

一旦你將版本新增到客戶端,任何由此客戶端啟動的協作流程將會使用版本 1.0.0。 該版本是一個簡單的字串,接受任意值。

在客戶端提供版本後,也會讓它在 TaskOrchestration中提供,這表示你可以在條件語句中使用該版本。 只要新版的編排版本具備適當的版本門控,舊版與新版編排版就能在同一客戶端上同時執行。

Example:

public TaskOrchestration create() {
    return ctx -> {
        List<String> results = new ArrayList<>();
        for (String city : new String[]{ "Seattle", "Amsterdam", "Hyderabad", "Kuala Lumpur", "Shanghai", "Tokyo" }) {
            results.add(ctx.callActivity("SayHello", city, String.class).await());
            if (VersionUtils.compareVersions(ctx.getVersion(), "2.0.0") >= 0) {
                // Simulate a delay for newer versions
                results.add(ctx.callActivity("SayGoodbye", city, String.class).await());
            }
        }
        ctx.complete(results);
    };
}

一旦你將版本加入到客戶端,任何由此客戶端啟動的編排都會使用 1.0.0 版本。 該版本是一個簡單的字串,使用解析 packaging.version,支援語意版本比較,並接受任何值。

在客戶端提供版本後,也會在task.OrchestrationContext中提供,這意味著你可以在條件語句中使用該版本。 只要新版的編排版本具備適當的版本門控,舊版與新版編排版就能在同一客戶端上同時執行。

Example:

def orchestrator(ctx: task.OrchestrationContext, _):
    if ctx.version == "1.0.0":
        # For version 1.0.0, we use the original logic
        result: int = yield ctx.call_activity(activity_v1, input="input for v1")
    elif ctx.version == "2.0.0":
        # For version 2.0.0, we use the updated logic
        result: int = yield ctx.call_activity(activity_v2, input="input for v2")
    else:
        raise ValueError(f"Unsupported version: {ctx.version}")
    return {
        'result': result,
    }

在這個例子中,我們將 SayGoodbye 活動添加到 HelloCities 編排中。 此活動僅適用於編排版本 2.0.0及更新版本。 使用簡單條件陳述,任何版本小於 的 2.0.0 編排都能繼續運作,且任何新的編排都包含該新活動。

使用用戶端版本設定的時機

雖然用戶端版本管理提供了最簡單的版本編排機制,但與版本互動可能非常耗費程式設計。 如果有以下情況,請使用客戶端版本管理:

  • 你想要所有版本都有標準版本,或者
  • 你需要針對特定版本自訂邏輯。

工作者為基礎的版本控制

雖然協調流程仍需用戶端版本來設定版本,但工作人員型版本管理方法能協助您在編排中避免用到條件判斷。 工作人員會在開始執行前,選擇如何對不同版本的協調流程採取行動。

工作程序版本控制需要設定下列欄位:

  1. 工作人員的版本。

  2. 預設版本適用於由工作人員啟動的子協調流程。

  3. 工作人員用來與協調流程版本配對的原則。

    名稱 說明
    沒有 在處理工作時,版本不會被考慮
    Strict 協調流程和背景工作角色中的版本必須完全相符
    CurrentOrOlder 協調流程中的版本必須等於或小於背景工作角色中的版本
  4. 如果版本不符合比對原則,工作人員將採取的原則。

    名稱 說明
    拒絕 協調流程被工作人員拒絕,但仍留在工作佇列中以在稍後再進行嘗試。
    失敗 協調流程失敗,且已從工作佇列中移除

類似於用戶端版本管理,你可以透過標準主機建構器模式設定這些欄位。

備註

自 v1.9.0 起可在 .NET SDK (Microsoft.DurableTask.Worker.AzureManaged) 中使用。

builder.Services.AddDurableTaskWorker(builder =>
{
    builder.AddTasks(r => r.AddAllGeneratedTasks());
    builder.UseDurableTaskScheduler(connectionString);
    builder.UseVersioning(new DurableTaskWorkerOptions.VersioningOptions
    {
        Version = "1.0.0",
        DefaultVersion = "1.0.0",
        MatchStrategy = DurableTaskWorkerOptions.VersionMatchStrategy.Strict,
        FailureStrategy = DurableTaskWorkerOptions.VersionFailureStrategy.Reject,
    });
});

備註

自 v1.6.0 起可在 Java SDK (com.microsoft:durabletask-client) 中使用。

private static DurableTaskGrpcWorker createTaskHubServer() {
    DurableTaskGrpcWorkerBuilder builder = new DurableTaskGrpcWorkerBuilder();
    builder.useVersioning(new DurableTaskGrpcWorkerVersioningOptions(
            "1.0",
            "1.0",
            DurableTaskGrpcWorkerVersioningOptions.VersionMatchStrategy.CURRENTOROLDER,
            DurableTaskGrpcWorkerVersioningOptions.VersionFailureStrategy.REJECT));

    // Orchestrations can be defined inline as anonymous classes or as concrete classes
    builder.addOrchestration(new TaskOrchestrationFactory() {
        @Override
        public String getName() { return "HelloCities"; }

        @Override
        public TaskOrchestration create() {
            return ctx -> {
                List<String> results = new ArrayList<>();
                for (String city : new String[]{ "Seattle", "Amsterdam", "Hyderabad", "Kuala Lumpur", "Shanghai", "Tokyo" }) {
                    results.add(ctx.callActivity("SayHello", city, String.class).await());
                }
                ctx.complete(results);
            };
        }
    });

    // Activities can be defined inline as anonymous classes or as concrete classes
    builder.addActivity(new TaskActivityFactory() {
        @Override
        public String getName() { return "SayHello"; }

        @Override
        public TaskActivity create() {
            return ctx -> {
                String input = ctx.getInput(String.class);
                return "Hello, " + input + "!";
            };
        }
    });

    return builder.build();
}
with DurableTaskSchedulerWorker(host_address=endpoint, secure_channel=secure_channel,
                                taskhub=taskhub_name, token_credential=credential) as w:
    # This worker is versioned for v2, as the orchestrator code has already been updated
    # CURRENT_OR_OLDER allows this worker to process orchestrations versioned below 2.0.0 - e.g. 1.0.0
    w.use_versioning(worker.VersioningOptions(
        version="2.0.0",
        default_version="2.0.0",
        match_strategy=worker.VersionMatchStrategy.CURRENT_OR_OLDER,
        failure_strategy=worker.VersionFailureStrategy.FAIL
    ))
    w.add_orchestrator(orchestrator)
    w.add_activity(activity_v1)
    w.add_activity(activity_v2)
    w.start()

失效策略

拒絕

當期望的行為是讓協調流程在之後或在不同的工作人員上重試時,請使用Reject失敗原則。 在 Reject 發生失敗時:

  1. 一個協調流程被拒絕並返回到工作佇列。
  2. 協調流程被移出工作佇列。
  3. 移出工作佇列的協調流程可能會分配到不同的工作人員,或是再次由同一個工作人員處理。

這個過程會重複,直到有能處理編排的工作人員可用。 此策略能無縫處理更新編排的部署。 隨著部署進行,無法處理協調流程的工作人員會加以拒絕,而能處理的工作人員就會進行處理。

能夠混合工作人員與協調流程版本,允許像藍綠部署之類的情境。

Fail

當沒有其他預期版本時,請使用Fail失敗原則。 在此情況下,新版本是異常現象,任何工作人員都不應該嘗試處理它。 持久任務排程器未能完成調排,導致進入終端狀態。

使用工作程序版本控制的時機

在完全不應執行未知或不支援的協調流程的情境中,請使用工作人員版本管理。 背景工作角色版本設定會停止協調流程執行,而不是將版本處理程式碼放在背景工作角色中。 此方法允許更簡單的編排程式碼。 無需修改程式碼,就能處理各種部署情境,例如藍綠部署。

後續步驟