Dela via


Versionshantering för orkestrering (förhandsversion)

Ett viktigt område att tänka på när du använder ett hållbart orkestreringssystem är hur du hanterar uppgradering/nedgradering av orkestreringar. När en orkestrering avbryts och senare återupptas (till exempel under en värduppdatering) spelar Durable Task Scheduler upp orkestreringens händelser igen. Detta görs för att säkerställa tillförlitlighet - systemet spelas upp för att säkerställa att alla tidigare steg utfördes korrekt innan nästa steg tas - vilket är ett grundläggande löfte om det hållbara körningsparadigmet. Så om en orkestrering ändras mellan utrullningar kanske stegen det tar inte längre är desamma. Om detta inträffar genererar systemet en NonDeterministicError istället för att låta orkestreringen fortsätta.

Versionshantering av orkestrering hjälper till att förhindra problem som rör icke-determinism, så att du kan arbeta sömlöst med nya (eller gamla) orkestreringar. Durable Task Scheduler har två olika versionsformat som kommer att utforskas nedan. Observera att de olika versionsformaten kan användas separat eller tillsammans.

Viktigt!

För närvarande är SDK:erna för varaktiga uppgifter inte tillgängliga för JavaScript och PowerShell.

Viktigt!

För närvarande är SDK:erna för varaktiga uppgifter inte tillgängliga för JavaScript och PowerShell.

Viktigt!

Versionshantering är för närvarande inte tillgängligt i Python SDK.

Klient-/kontextbaserad villkorlig versionshantering

För att en orkestrering ska ha en version måste den först anges i klienten. För .NET SDK görs detta via standardtilläggen för värdbyggare enligt nedan:

Anmärkning

Finns i .NET SDK (Microsoft.DurableTask.Client.AzureManaged) sedan v1.9.0.

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

Anmärkning

Finns i Java SDK (com.microsoft:durabletask-client) sedan v1.6.0.

public DurableTaskClient durableTaskClient(DurableTaskProperties properties) {
    // Create client using Azure-managed extensions
    return DurableTaskSchedulerClientExtensions.createClientBuilder(properties.getConnectionString())
        .defaultVersion("1.0")
        .build();
}

När det har lagts till använder all orkestrering som startas av den här värden versionen 1.0.0. Själva versionen är en enkel sträng och accepterar alla värden. SDK:et försöker dock konvertera det till . NET:s System.Version. Om det kan konverteras används det biblioteket för jämförelse, om inte, en enkel strängjämförelse används.

Genom att ange versionen i klienten blir den också tillgänglig i TaskOrchestrationContext. Det innebär att versionen kan användas i villkorssatser. Så länge nyare versioner av en orkestrering har korrekt versionsbegränsning, kan både den gamla och den nya versionen av orkestreringen köras samtidigt på samma värd. Ett exempel på hur versionen kan användas är:

[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;
    }
}
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);
    };
}

I det här exemplet har vi lagt till en SayGoodbye aktivitet i HelloCities orkestreringen. Detta anropas endast om orkestreringsversionen är minst 2.0.0. Med den enkla villkorliga instruktionen fortsätter all orkestrering med en mindre version än 2.0.0 att fungera och all ny orkestrering kommer att ha den nya aktiviteten i den.

När du ska använda klientversionshantering

Klientversionering ger den enklaste mekanismen för versionering av orkestreringar, men att arbeta med versionen är också det mest programmeringsintensiva. I huvudsak är de två funktioner som klientversionering ger möjlighet att ange en version för alla orkestreringar och möjligheten att programmatiskt hantera versionen i orkestreringen. Den bör användas om en standardversion önskas i alla versioner eller om anpassad logik kring specifika versioner krävs.

Arbetarbaserad versionshantering

En ytterligare strategi som kan användas för att hantera versioner är att konfigurera versionshantering för arbetare. Orkestreringar behöver fortfarande en klientversion för att få versionen inställd, men med den här metoden kan användaren undvika villkor i sina orkestreringar. Med versionshantering för arbetare kan arbetaren själv välja hur de ska agera på olika versioner av orkestrering innan orkestreringarna börjar köras. Versionshantering för arbetare kräver att följande fält anges:

  1. Versionen av arbetaren själv
  2. Standardversionen som ska tillämpas på delorchestrationer som startas av arbetaren
  3. Den strategi som arbetaren ska använda för att matcha orkestreringens version
  4. Den strategi som arbetaren bör använda om versionen inte uppfyller matchningsstrategin

De olika matchningsstrategierna är följande:

Namn Beskrivning
Ingen Versionen beaktas inte när arbetet bearbetas
Sträng Versionen i orkestreringen och arbetaren måste matcha exakt
AktuellEllerÄldre Versionen i orkestreringen måste vara lika med eller mindre än versionen i arbetaren

De olika felstrategierna är följande:

Namn Beskrivning
Avvisa Orkestreringen avvisas av arbetaren men finns kvar i arbetskön för att bearbetas på nytt senare
Fel Orkestreringen misslyckas och tas bort från arbetskön

På samma sätt som klientversionering, anges alla dessa via standardmönstret för host-byggarmönster.

Anmärkning

Tillgänglig i .NET SDK (Microsoft.DurableTask.Worker.AzureManaged) sedan v1.9.0.

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,
    });
});

Anmärkning

Finns i Java SDK (com.microsoft:durabletask-client) sedan v1.6.0.

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();
}

Felstrategin Reject bör användas när det önskade beteendet är att orkestreringen ska försöka igen vid ett senare tillfälle/på en annan arbetare. När en orkestrering avvisas returneras den helt enkelt till arbetskön. När det är dequeued igen, kan det landa på en annan arbetare eller samma igen. Processen upprepas tills en arbetare som faktiskt kan hantera orkestreringen är tillgänglig. Den här strategin möjliggör sömlös hantering av distributioner där orkestreringen uppdateras. När distributionen fortskrider kommer arbetarna som inte kan hantera orkestreringen att avvisa den, medan de som kan hantera den kommer att bearbeta den. Möjligheten att ha blandade versioner av arbetare och orkestrering möjliggör scenarier som blå-grön driftsättning.

Felstrategin Fail bör användas när inga andra versioner förväntas. I det här fallet är den nya versionen en avvikelse och ingen arbetare ska ens försöka arbeta med den. Därför kommer Durable Task Scheduler att misslyckas med orkestreringen och placera den i ett terminaltillstånd.

När du ska använda arbetsversionering

Versionshantering av arbetare ska användas i scenarier där orkestreringar av en okänd eller version som inte stöds inte ska köras alls. I stället för att placera versionshanteringskod i arbetaren, förhindrar arbetarnas versionering att orkestreringen någonsin körs. Detta möjliggör mycket enklare orkestreringskod. Utan några kodändringar kan olika distributionsscenarier hanteras, till exempel blågröna distributioner som nämnts tidigare.