Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Versionshantering av orkestrering hanterar den grundläggande utmaningen med att distribuera ändringar till orkestrerarens funktioner samtidigt som den deterministiska körningsmodellen som Durable Functions kräver bibehålls. Utan denna funktion skulle låsta förändringar i orkestrerarelogik eller aktivitetsfunktionssignaturer leda till att orkestreringsinstanser misslyckas under uppspelningen, eftersom dessa skulle bryta mot determinismkravet som säkerställer tillförlitlig körning av orkestreringen. Den här inbyggda funktionen ger automatisk versionsisolering med minimal konfiguration. Det är serverdelsoberoende, så det kan användas av appar som använder någon av Durable Functions lagringsproviders, inklusive Durable Task Scheduler.
Note
För användare av Durable Task Scheduler, om du använder Durable Task SDK:er istället för Durable-funktioner, bör du läsa versionsartikeln om Durable Task SDK:er.
Terminology
Den här artikeln använder två relaterade men distinkta termer:
- Orchestrator-funktion (eller helt enkelt "orchestrator"): Refererar till funktionskoden som definierar arbetsflödeslogik – mallen eller skissen för hur ett arbetsflöde ska köras.
- Orkestreringsinstans (eller helt enkelt "orkestrering"): Refererar till en specifik körning av en orkestreringsfunktion med sitt eget tillstånd, instans-ID och indata. Flera orkestreringsinstanser kan köras samtidigt från samma orkestreringsfunktion.
Att förstå den här skillnaden är avgörande för versionshantering av orkestrering, där orchestrator-funktionskoden innehåller versionsmedveten logik, medan orkestreringsinstanser är permanent associerade med en specifik version när de skapas.
Så här fungerar det
Versionsfunktionen för orkestrering fungerar enligt följande grundläggande principer:
Versionsassociation: När en orkestreringsinstans skapas hämtar den en version som är permanent associerad med den.
Versionsmedveten körning: Orchestrator-funktionskoden kan undersöka versionsvärdet som är associerat med den aktuella orkestreringsinstansen och grenkörningen i enlighet med detta.
Bakåtkompatibilitet: Arbetare som kör nyare orkestreringsversioner kan fortsätta köra orkestreringsinstanser som skapats av äldre orchestrator-versioner.
Forward Protection: Körningen förhindrar automatiskt att arbetare som kör äldre orkestreringsversioner kör orkestreringar som startas av nyare orchestrator-versioner.
Important
Versionshantering av orkestrering finns för närvarande i offentlig förhandsversion.
Förutsättningar
Innan du använder orkestreringsversioner kontrollerar du att du har de paketversioner som krävs för programmeringsspråket.
Om du använder ett non-.NET språk (JavaScript, Python, PowerShell eller Java) med tilläggspaket måste funktionsappen referera till Tilläggspaket version 4.26.0 eller senare.
extensionBundle Konfigurera intervallet i host.json så att den lägsta versionen är minst 4.26.0, till exempel:
{
"version": "2.0",
"extensionBundle": {
"id": "Microsoft.Azure.Functions.ExtensionBundle",
"version": "[4.26.0, 5.0.0)"
}
}
Mer information om hur du väljer och uppdaterar paketversioner finns i konfigurationsdokumentationen för tilläggspaket .
Använd Microsoft.Azure.Functions.Worker.Extensions.DurableTask version 1.5.0 eller senare.
Grundläggande användning
Det vanligaste användningsfallet för orkestreringsversioner är när du behöver göra brytande ändringar i din orkestreringslogik samtidigt som aktiva orkestreringsinstanser fortsätter att köras med sin ursprungliga version. Allt du behöver göra är att uppdatera defaultVersion i din host.json och ändra orkestreringskoden för att kontrollera orkestreringsversionen och grenkörningen i enlighet med detta. Nu ska vi gå igenom de steg som krävs.
Note
Det beteende som beskrivs i det här avsnittet riktar sig mot de vanligaste situationerna, och det är vad standardkonfigurationen tillhandahåller. Den kan dock ändras om det behövs (se Avancerad användning för mer information).
Steg 1: defaultVersion-konfiguration
Om du vill konfigurera standardversionen för orkestreringarna måste du lägga till eller uppdatera defaultVersion inställningen i host.json filen i Azure Functions-projektet:
{
"extensions": {
"durableTask": {
"defaultVersion": "<version>"
}
}
}
Versionssträngen kan följa valfritt format som passar din versionsstrategi:
- Versionshantering i flera delar:
"1.0.0","2.1.0" - Enkel numrering:
"1","2" - Datumbaserad:
"2025-01-01" - Anpassat format:
"v1.0-release"
När du har angett defaultVersionassocieras alla nya orkestreringsinstanser permanent med den versionen.
Regler för versionsjämförelse
När Strict-strategin eller CurrentOrOlder-strategin har valts (se Versionsmatchning) jämför körningen versionen av orkestreringsinstansen med defaultVersion-värdet för arbetaren med hjälp av följande regler.
- Tomma eller null-versioner behandlas som lika.
- En tom eller null-version anses vara äldre än någon definierad version.
- Om båda versionerna kan parsas som
System.VersionCompareToanvänds metoden. - Annars utförs skiftlägesokänslig strängjämförelse.
Steg 2: Orchestrator-funktionslogik
Om du vill implementera versionsmedveten logik i din orchestrator-funktion kan du använda kontextparametern som skickas till orchestrator för att komma åt den aktuella orkestreringsinstansens version, vilket gör att du kan förgrena orkestreringslogik baserat på versionen.
Important
När du implementerar versionsmedveten logik är det mycket viktigt att bevara exakt orkestreringslogik för äldre versioner. Ändringar i sekvensen, ordningen eller signaturen för aktivitetsanrop för befintliga versioner kan störa deterministisk återspelning och orsaka att pågående orkestreringar misslyckas eller ger felaktiga resultat. De gamla versionskodsökvägarna måste förbli oförändrade när de har distribuerats.
[Function("MyOrchestrator")]
public static async Task<string> RunOrchestrator(
[OrchestrationTrigger] TaskOrchestrationContext context)
{
if (context.Version == "1.0")
{
// Original logic for version 1.0
...
}
else if (context.Version == "2.0")
{
// New logic for version 2.0
...
}
...
}
Note
Egenskapen context.Version är skrivskyddad och återspeglar den version som var permanent associerad med orkestreringsinstansen när den skapades. Du kan inte ändra det här värdet under orkestreringskörningen. Om du vill ange en version med andra medel än host.jsonkan du göra det när du startar en orkestreringsinstans med orkestreringsklient-API:erna (se Starta nya orkestreringar och underorkestreringar med specifika versioner).
Tip
sv-SE: Om du precis har börjat använda orkestreringsversioner och du redan har aktiva orkestreringar som skapades innan du angav en defaultVersion, kan du fortfarande lägga till defaultVersion-inställningen i din host.json nu. För alla tidigare skapade orkestreringar returnerar context.Versionnull (eller ett motsvarande språkberoende värde), så att du kan strukturera orkestreringslogik för att hantera både den äldre (null-versionen) och nya versionsorkestreringar i enlighet med detta. Följande är de språkberoende värdena för att söka efter det äldre fallet:
- C#:
context.Version == nullellercontext.Version is null - JavaScript:
context.df.version == null - Python:
context.version is None - PowerShell:
$null -eq $Context.Version - Java:
context.getVersion() == nullObservera också att det är ekvivalent att inte ange"defaultVersion": nullalls ihost.json.
Tip
Beroende på din situation kanske du föredrar förgrening på olika nivåer. Du kan göra en lokal ändring exakt där den här ändringen krävs, som exemplet visar. Du kan också förgrena på en högre nivå, även på nivå för hela orkestratorimplementeringen, vilket introducerar viss kodupprepning, men kan hålla körningsflödet tydligt. Det är upp till dig att välja den metod som passar bäst för ditt scenario och kodningsstil.
Vad händer efter distributionen?
Här är vad du kan förvänta dig när du distribuerar din uppdaterade orchestrator-funktion med den nya versionslogik:
Arbetssamarbete: Arbetare som innehåller den nya orchestrator-funktionskoden startar, medan vissa arbetare med den gamla koden är potentiellt fortfarande aktiva.
Versionstilldelning för nya instanser: Alla nya orkestreringar och underorkestreringar som skapats av de nya arbetarna får versionen från
defaultVersiontilldelad till dem.Ny arbetskompatibilitet: Nya arbetare kan bearbeta både de nyskapade orkestreringarna och de tidigare befintliga orkestreringarna eftersom ändringarna som utfördes i steg 2 i föregående avsnitt säkerställer bakåtkompatibilitet genom versionsmedveten förgreningslogik.
Begränsningar för gamla arbetare: Gamla arbetare får endast bearbeta orkestreringarna med en version som är lika med eller lägre än den version som anges i deras egen
defaultVersionihost.json, eftersom de inte förväntas ha orchestrator-kod som är kompatibel med nyare versioner. Den här begränsningen förhindrar körningsfel och oväntat beteende.
Note
Versionshantering av orkestrering påverkar inte medarbetarens livscykel. Azure Functions-plattformen hanterar etablering och avaktivering av arbetare baserat på vanliga regler beroende på värdalternativ.
Exempel: Ersätta en aktivitet i sekvensen
Det här exemplet visar hur du ersätter en aktivitet med en annan aktivitet mitt i en sekvens med hjälp av orkestreringsversioner.
Version 1.0
host.json konfiguration:
{
"extensions": {
"durableTask": {
"defaultVersion": "1.0"
}
}
}
Orchestrator-funktion:
[Function("ProcessOrderOrchestrator")]
public static async Task<string> ProcessOrder(
[OrchestrationTrigger] TaskOrchestrationContext context)
{
var orderId = context.GetInput<string>();
await context.CallActivityAsync("ValidateOrder", orderId);
await context.CallActivityAsync("ProcessPayment", orderId);
await context.CallActivityAsync("ShipOrder", orderId);
return "Order processed successfully";
}
Version 2.0 med rabattbearbetning
host.json konfiguration:
{
"extensions": {
"durableTask": {
"defaultVersion": "2.0"
}
}
}
Orchestrator-funktion:
using DurableTask.Core.Settings;
[Function("ProcessOrderOrchestrator")]
public static async Task<string> ProcessOrder(
[OrchestrationTrigger] TaskOrchestrationContext context)
{
var orderId = context.GetInput<string>();
await context.CallActivityAsync("ValidateOrder", orderId);
if (VersioningSettings.CompareVersions(context.Version, "1.0") <= 0)
{
// Preserve original logic for existing instances
await context.CallActivityAsync("ProcessPayment", orderId);
}
else // a higher version (including 2.0)
{
// New logic with discount processing (replaces payment processing)
await context.CallActivityAsync("ApplyDiscount", orderId);
await context.CallActivityAsync("ProcessPaymentWithDiscount", orderId);
}
await context.CallActivityAsync("ShipOrder", orderId);
return "Order processed successfully";
}
Avancerad användning
För mer avancerade versionsscenarier kan du konfigurera andra inställningar för att styra hur runtime hanterar versionsöverensstämmelser och avvikelser.
Tip
Använd standardkonfigurationen (CurrentOrOlder med Reject) för de flesta scenarier för att aktivera säkra rullande distributioner samtidigt som orkestreringstillståndet bevaras under versionsövergångar. Vi rekommenderar att du fortsätter med den avancerade konfigurationen endast om du har specifika krav som inte kan uppfyllas med standardbeteendet.
Versionsmatchning
Inställningen versionMatchStrategy avgör hur körmiljön matchar orkestreringsversioner när orkestreringsfunktioner läses in. Den styr vilka orkestreringsinstanser som en arbetare kan bearbeta baserat på versionskompatibilitet.
Configuration
{
"extensions": {
"durableTask": {
"defaultVersion": "<version>",
"versionMatchStrategy": "CurrentOrOlder"
}
}
}
Tillgängliga strategier
None(rekommenderas inte): Ignorera orkestreringsversionen helt. Allt arbete som tas emot bearbetas oavsett version. Den här strategin inaktiverar effektivt versionskontroll och gör att alla arbetare kan bearbeta alla orkestreringsinstanser.Strict: Bearbeta endast uppgifter från orkestreringar med exakt samma version som den version som anges avdefaultVersioni arbetarenshost.json. Den här strategin ger den högsta nivån av versionsisolering men kräver noggrann distributionssamordning för att undvika övergivna orkestrationer. Konsekvenserna av versionsmatchningsfel beskrivs i avsnittet Hantering av versionsmatchningsfel .CurrentOrOlder(standard): Bearbeta uppgifter från orkestreringar vars version är mindre än eller lika med den version som anges avdefaultVersioni arbetarenshost.json. Den här strategin möjliggör bakåtkompatibilitet, vilket gör det möjligt för nyare arbetare att hantera orkestreringar som startats av äldre orkestreringsversioner samtidigt som äldre arbetare inte kan bearbeta nyare orkestreringar. Konsekvenserna av versionsmatchningsfel beskrivs i avsnittet Hantering av versionsmatchningsfel .
Hantering av versionsmatchningsfel
Inställningen versionFailureStrategy avgör vad som händer när en orkestreringsinstansversion inte matchar den aktuella defaultVersion.
Configuration:
{
"extensions": {
"durableTask": {
"defaultVersion": "<version>",
"versionFailureStrategy": "Reject"
}
}
}
Tillgängliga strategier:
Reject(standard): Bearbeta inte orkestreringen. Orkestreringsinstansen förblir i sitt aktuella tillstånd och kan göras om senare när en kompatibel arbetare blir tillgänglig. Den här strategin är det säkraste alternativet eftersom den bevarar orkestreringstillståndet.Fail: Orkestreringen misslyckades. Den här strategin avslutar omedelbart orkestreringsinstansen med ett feltillstånd, detta kan vara lämpligt i situationer där versionsinkonsekvenser indikerar allvarliga distributionsproblem.
Starta nya orkestreringar och underorkestreringar med specifika versioner
Som standardinställning skapas alla nya orkestreringsinstanser med den aktuella defaultVersion som anges i host.json konfigurationen. Du kan dock ha scenarier där du behöver skapa orkestreringar med en viss version, även om den skiljer sig från den aktuella standardinställningen.
När du ska använda specifika versioner:
- Gradvis migrering: Du vill fortsätta att skapa orkestreringar med en äldre version även när du har distribuerat en nyare version.
- Testscenarier: Du måste testa specifika versionsbeteenden i produktionen.
- Återställningssituationer: Du måste tillfälligt återgå till att skapa instanser med en tidigare version.
- Versionsspecifika arbetsflöden: Olika affärsprocesser kräver olika orkestreringsversioner.
Du kan åsidosätta standardversionen genom att ange ett specifikt versionsvärde när du skapar nya orkestreringsinstanser med hjälp av dirigeringsklient-API:erna. Detta ger detaljerad kontroll över vilken version varje ny orkestreringsinstans använder.
[Function("HttpStart")]
public static async Task<HttpResponseData> HttpStart(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post")] HttpRequestData req,
[DurableClient] DurableTaskClient client,
FunctionContext executionContext)
{
var options = new StartOrchestrationOptions
{
Version = "1.0"
};
string instanceId = await client.ScheduleNewOrchestrationInstanceAsync("ProcessOrderOrchestrator", orderId, options);
// ...
}
Du kan också starta underorkestreringar med specifika versioner från en orkestreringsfunktion:
[Function("MainOrchestrator")]
public static async Task<string> RunMainOrchestrator(
[OrchestrationTrigger] TaskOrchestrationContext context)
{
var subOptions = new SubOrchestratorOptions
{
Version = "1.0"
};
var result = await context.CallSubOrchestratorAsync<string>("ProcessPaymentOrchestrator", orderId, subOptions);
// ...
}
Ta bort äldre kodvägar
Med tiden kanske du vill ta bort legacykodvägar från dina orkestreringsfunktioner för att förenkla underhåll och minska teknisk skuld. Att ta bort kod måste dock göras noggrant för att undvika att bryta befintliga orkestreringsinstanser.
När det är säkert att ta bort äldre kod:
- Alla orkestreringsexemplar som använder den gamla versionen har slutförts: har lyckats, har misslyckats eller har blivit avslutade.
- Inga nya orkestreringsinstanser skapas med den gamla versionen
- Du har verifierat genom övervakning eller frågor att inga instanser körs med den äldre versionen
- En tillräcklig tidsperiod har passerat sedan den gamla versionen senast distribuerades (med tanke på dina krav på affärskontinuitet)
Metodtips för borttagning:
- Övervaka aktivt aktiva instanser: Använd DURABLE Functions-hanterings-API:er för att fråga efter instanser med hjälp av specifika versioner.
- Ange kvarhållningsprinciper: Definiera hur länge du tänker upprätthålla bakåtkompatibilitet för varje version.
- Ta bort stegvis: Överväg att ta bort en version i taget i stället för flera versioner samtidigt.
- Borttagning av dokument: Underhålla tydliga poster för när versioner togs bort och varför.
Warning
Om du tar bort äldre kodsökvägar medan orkestreringsinstanser fortfarande kör dessa versioner kan det orsaka deterministiska omspelningsfel eller oväntat beteende. Kontrollera alltid att inga instanser använder den äldre versionen innan du tar bort koden.
Metodtips
Versionshantering
-
Använd versionshantering i flera delar: Anta ett konsekvent versionsschema som
major.minor.patch. - Dokumentera viktiga ändringar: Dokumentera tydligt vilka ändringar som kräver en ny version.
- Planera versionslivscykeln: Definiera när du vill ta bort äldre kodsökvägar.
Kodorganisation
- Separat versionslogik: Använd tydlig förgrening eller separata metoder för olika versioner.
- Bevara determinism: Undvik att ändra befintlig versionslogik när den har distribuerats. Om ändringar är absolut nödvändiga (till exempel kritiska felkorrigeringar) ser du till att de behåller deterministiskt beteende och inte ändrar åtgärdssekvensen, eller förväntar sig att de nyare orkestreringsversionerna misslyckas vid bearbetning av äldre orkestreringar.
- Testa noggrant: Testa alla versionssökvägar, särskilt under övergångar.
Övervakning och observerbarhet
- Loggversionsinformation: Inkludera version i loggningen för enklare felsökning.
- Övervaka versionsdistribution: Spåra vilka versioner som körs aktivt.
- Konfigurera aviseringar: Övervaka eventuella versionsrelaterade fel.
Troubleshooting
Vanliga problem
Problem: Orkestreringsinstanser som skapats med version 1.0 misslyckas när version 2.0 har distribuerats
- Lösning: Se till att kodvägen version 1.0 i din orkestrator förblir precis densamma. Eventuella ändringar i körningssekvensen kan bryta deterministisk repris.
Problem: Arbetare som kör äldre orkestreringsversioner kan inte köra nya orkestreringar
-
Lösning: Detta är förväntat beteende. Körsystemet förhindrar avsiktligt äldre arbetarprocesser från att exekvera orkestreringar med nyare versioner för att upprätthålla säkerheten. Se till att alla medarbetare uppdateras till den senaste orchestratormjukvaran och att deras
defaultVersion-inställning ihost.jsonuppdateras i enlighet med detta. Du kan ändra det här beteendet om det behövs med hjälp av avancerade konfigurationsalternativ (se Avancerad användning för mer information).
-
Lösning: Detta är förväntat beteende. Körsystemet förhindrar avsiktligt äldre arbetarprocesser från att exekvera orkestreringar med nyare versioner för att upprätthålla säkerheten. Se till att alla medarbetare uppdateras till den senaste orchestratormjukvaran och att deras
Problem: Versionsinformationen är inte tillgänglig i orchestrator (
context.Versionellercontext.getVersion()är null, oavsettdefaultVersioninställning)- Lösning: Kontrollera avsnittet Krav för att säkerställa att din miljö uppfyller alla krav för orkestreringsversioner.
Problem: Orkestreringar av en nyare version gör mycket långsamma framsteg eller har fastnat helt
-
Lösning: Problemet kan ha olika rotåtgärder:
-
Otillräckligt med nyare arbetare: Se till att ett tillräckligt antal arbetare som innehåller en likvärdig eller högre version i
defaultVersiondistribueras och är aktiva för att hantera nyare orkestreringar. - Orkestreringsdirigeringsinterferens från äldre arbetare: Gamla arbetare kan störa dirigeringsmekanismen för orkestrering, vilket gör det svårare för nya arbetare att plocka upp orkestreringar för bearbetning. Detta kan vara särskilt märkbart när du använder vissa lagringsproviders (Azure Storage eller MSSQL). Normalt sett säkerställer Azure Functions-plattformen att gamla arbetare tas bort strax efter en distribution, så eventuella fördröjningar är vanligtvis inte betydande. Men om du använder en konfiguration som gör att du kan styra livscykeln för äldre arbetare kontrollerar du att de äldre arbetarna slutligen stängs av. Du kan också överväga att använda Durable Task Scheduler eftersom det ger en förbättrad routningsmekanism som är mindre känslig för det här problemet.
-
Otillräckligt med nyare arbetare: Se till att ett tillräckligt antal arbetare som innehåller en likvärdig eller högre version i
-
Lösning: Problemet kan ha olika rotåtgärder: