Driftsättning utan störningar för Durable Functions

Den tillförlitliga körmodellen av Durable Functions kräver att orkestreringarna är deterministiska, vilket skapar en utmaning när du distribuerar uppdateringar. När en distribution innehåller icke-bakåtkompatibla ändringar , till exempel ändrade aktivitetsfunktionssignaturer eller ändrad orkestreringslogik, misslyckas orkestreringsinstanser under flygning. Den här situationen är särskilt ett problem för långvariga orkestreringar, som kan representera timmar eller dagar av arbete.

Anmärkning

Strategierna i den här artikeln förutsätter att du använder standardprovidern Azure Storage för Durable Functions. Om du använder en annan lagringsprovider kanske inte vägledningen gäller. Orkestreringsstrategin för versionshantering är undantaget – den fungerar med alla lagringsbackends. Mer information om alternativen för lagringsleverantörer finns i Durable Functions lagringsleverantörer.

I följande tabell jämförs fyra strategier för att uppnå distribution utan stillestånd. Välj den strategi som bäst matchar din arbetsbelastning:

Strategi När det bör användas Fördelar Nackdelar
Versionshantering för orkestrering (rekommenderas) Applikationer med brytande förändringar som kräver flera orkestreringsversioner som körs samtidigt. Aktiverar distributioner utan stilleståndstid med ändringar som bryter kompatibilitet.
Inbyggd funktion som kräver minimal konfiguration.
Fungerar med valfri lagringsbackend.
Kräver noggranna orchestrator-kodändringar för versionskompatibilitet.
Namnbaserad versionshantering Program med ovanliga ändringar som bryter kompatibiliteten där enkelhet föredras. Enkelt att implementera. Ökad funktionsappstorlek i minne och antal funktioner.
Kodduplicering.
Statuskontroll med slot System med kortlivade orchestreringar (under 24 timmar) och förutsägbara mellanrum mellan exekveringar. Enkel kodbas.
Kräver inte ytterligare funktionsapphantering.
Kräver ytterligare hantering av lagringskonto eller uppgiftsnav.
Kräver perioder då inga orkestreringar körs.
Programroutning System med kontinuerligt pågående orkestreringar (över 24 timmar) eller ofta överlappande körningar utan inaktiva fönster. Hanterar nya versioner av system med kontinuerligt pågående orkestreringar som har icke-bakåtkompatibla ändringar. Kräver en intelligent applikationsrouter.
Kan nå det maximala antalet funktionsappar som tillåts av din prenumeration (standardvärdet är 100).

Versionshantering för orkestrering

Den rekommenderade strategin för avbrottsfri distribution med icke-bakåtkompatibla ändringar är funktionen för versionshantering i orkestrering. Det gör att olika versioner av orkestreringar kan samexistera och köras samtidigt utan konflikter.

Med versionshantering för orkestrering:

  • Varje orkestreringsinstans hämtar en version som är permanent associerad med den när den skapas.
  • Arbetare som kör nyare orchestrator-versioner kan fortsätta köra äldre versionsinstanser.
  • Arbetare som kör äldre orkestreringsversioner kan inte köra nyare versionsinstanser.
  • Orchestrator-funktioner kan undersöka deras version och grenkörning i enlighet med detta.

Den här metoden underlättar löpande uppgraderingar där arbetare som kör olika versioner av ditt program kan samexistera på ett säkert sätt. Till skillnad från de andra strategierna i den här artikeln är orkestreringsversioner serverdelsoberoende och fungerar med alla lagringsproviders.

Fullständiga implementeringssteg – inklusive hur du konfigurerar versionshantering, hanterar versionsgrening i orchestrator-kod och hanterar löpande uppgraderingar – finns i Versionshantering för orkestrering.

De återstående strategierna är alternativ för scenarier där orkestreringsversioner inte är lämpliga.

Namnbaserad versionshantering

Med den här strategin skapar du nya versioner av dina funktioner tillsammans med de gamla versionerna i samma funktionsapp. Varje funktions version blir en del av dess namn (till exempel MyOrchestrator_v1, MyOrchestrator_v2). Eftersom tidigare versioner bevaras kan orkestreringsinstanser under flygning fortsätta att referera till dem. Begäranden om nya orkestreringsinstanser anropar den senaste versionen, som din orkestreringsklientfunktion kan referera till från en appinställning. Följande diagram illustrerar den här metoden.

Skärmbild av det namnbaserade versionsstrategidiagrammet som visar hur funktionsversioner samexisterar i en Durable Functions app.

I den här strategin måste varje funktion kopieras och dess referenser till andra funktioner måste uppdateras. Du kan göra det enklare genom att skriva ett skript. Här är ett exempelprojekt med ett migreringsskript.

Anmärkning

Den här strategin använder distributionsplatser för att undvika driftstopp under distributionen. Mer detaljerad information om hur du skapar och använder nya distributionsplatser finns i Azure Functions distributionsplatser.

Statuskontroll med fack

Medan den aktuella versionen av funktionsappen körs i produktionsplatsen distribuerar du den nya versionen av funktionsappen till mellanlagringsplatsen. Innan du byter produktions- och mellanlagringsplatser kontrollerar du om det finns orkestreringsinstanser som körs. När alla orkestreringsinstanser har slutförts kan du göra växlingen. Den här strategin fungerar när du har förutsägbara tidsintervall när inga orkestreringsinstanser är i flygning. Det här är den bästa metoden när orkestreringarna inte är tidskrävande och när orkestreringskörningarna inte ofta överlappar varandra.

Konfiguration av funktionsapp

Använd följande procedur för att konfigurera det här scenariot.

  1. Lägg till distributionsutrymmen till din funktionsapp för testmiljö och produktion.

  2. För varje plats anger du appinställningen AzureWebJobsStorage till anslutningen för ett delat lagringskonto. Den här anslutningen till lagringskontot används av Azure Functions-körningen för att lagra åtkomstnycklarna för functions på ett säkert sätt. För den högsta säkerhetsnivån bör du använda en hanterad identitetsanslutning till ditt lagringskonto.

  3. För varje fack skapar du en ny appinställning, DurableManagementStoragetill exempel . Sätt dess värde till anslutningssträngen för olika lagringskonton. Dessa lagringskonton används av Durable Functions-tillägget för reliable execution. Använd ett separat lagringskonto för varje fack. Markera inte den här inställningen som en distributionsplatsinställning. Återigen är hanterade identitetsbaserade anslutningar de säkraste.

  4. I funktionsappens host.json fils durableTask-avsnitt anger du connectionStringName (Durable 2.x) eller azureStorageConnectionStringName (Durable 1.x) som namnet på appinställningen du skapade i steg 3.

Följande diagram visar den beskrivna konfigurationen av distributionsplatser och lagringskonton. I det här potentiella fördistributionsscenariot körs version 2 av en funktionsapp på produktionsplatsen, medan version 1 finns kvar i mellanlagringsplatsen.

Skärmbild av distributionsslottar och konfiguration av lagringskonton före byte av slottar för Durable Functions driftsättning utan stilleståndstid.

exempel på host.json

Följande JSON-fragment visar inställningen reťazec pripojenia i filen host.json.

{
  "version": 2.0,
  "extensions": {
    "durableTask": {
      "hubName": "MyTaskHub",
      "storageProvider": {
        "connectionStringName": "DurableManagementStorage"
      }
    }
  }
}

Anmärkning

För äldre Functions 1.x-appar använder du azureStorageConnectionStringName egenskapen direkt i avsnittet i durableTask stället för storageProvider.connectionStringName.

Konfiguration av CI/CD-pipeline

Konfigurera CI/CD-pipelinen så att den endast distribueras när funktionsappen inte har några väntande eller pågående orkestreringsinstanser. När du använder Azure-pipelines kan du skapa en funktion som söker efter dessa villkor, som i följande C#-exempel. Samma mönster gäller för andra språk – fråga efter orkestreringsinstanser med Pending eller Running status och returnera om det finns några.

[FunctionName("StatusCheck")]
public static async Task<IActionResult> StatusCheck(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestMessage req,
    [DurableClient] IDurableOrchestrationClient client,
    ILogger log)
{
    var runtimeStatus = new List<OrchestrationRuntimeStatus>();

    runtimeStatus.Add(OrchestrationRuntimeStatus.Pending);
    runtimeStatus.Add(OrchestrationRuntimeStatus.Running);

    var result = await client.ListInstancesAsync(new OrchestrationStatusQueryCondition() { RuntimeStatus = runtimeStatus }, CancellationToken.None);
    return (ActionResult)new OkObjectResult(new { HasRunning = result.DurableOrchestrationState.Any() });
}

Konfigurera sedan staging-gaten så att den väntar tills inga orkestreringar körs. Mer information finns i Versionsdistributionskontroll med portar

Screenshot av en Azure-pipelines distributionsportkonfiguration för Durable Functions distribution utan avbrott.

Azure-pipelines kontrollerar din funktionsapp för körande orkestreringsinstanser innan distributionen startar.

Skärmbild av en körd Azure-pipelines distributionsportkontroll för orkestreringsinstanser.

Nu ska den nya versionen av din funktionsapp distribueras till stagingmiljön.

Skärmbild av den nya versionen av Durable Functions-appen som distribuerats till stagingplatsen under en distribution utan avbrott.

Slutligen växlar du fack.

Programinställningar som inte har markerats som inställningar för distributionsfack växlas också, så version 2-appen behåller sin referens till lagringskonto A. Eftersom orkestreringstillståndet spåras i lagringskontot fortsätter alla orkestreringar som körs i version 2-appen att köras i det nya facket utan avbrott.

Skärmbild av slutförande av fackväxling med Durable Functions appinställningarna överflyttade till produktion.

Om du vill använda samma lagringskonto för båda platserna kan du ändra namnen på dina aktivitetshubbar. I det här fallet behöver du hantera tillståndet för dina slots och din apps HubName-inställningar. Mer information finns i Task-hubbar i Durable Functions.

Programroutning

Den här strategin är den mest komplexa, men det är det enda alternativet för system med kontinuerligt aktiva orkestreringar som aldrig har ett inaktivt fönster för fackbyten.

För den här strategin skapar du en application-router framför din Durable Functions – till exempel en Azure-funktion med HTTP-utlösare eller en API Management-instans som dirigeras baserat på versionshuvuden. Routern ansvarar för:

  • Distribuera funktionsappen.
  • Hantera vilken version av appen som är aktiv.
  • Dirigera orkestreringsbegäranden till rätt funktionsapp baserat på version.

Första gången en orkestreringsbegäran tas emot utför routern följande uppgifter:

  1. Skapar en ny funktionsapp i Azure.
  2. Distribuerar funktionsappens kod till den nya funktionsappen i Azure.
  3. Vidarebefordrar orkestreringsbegäran till den nya appen.

Routern hanterar tillståndet för vilken version av appens kod som distribueras till vilken funktionsapp i Azure.

Skärmbild av första gången programdirigering och distributionsflöde för Durable Functions distribution utan avbrott.

Routern dirigerar distributions- och orkestreringsbegäranden till lämplig funktionsapp baserat på den version som skickas med begäran. Den ignorerar patchversionen.

När du distribuerar en ny version av din app utan en ändring som bryter kompatibilitet, kan du öka patchversionen. Routern distribuerar till din befintliga funktionsapp och skickar begäranden för de gamla och nya versionerna av koden, som dirigeras till samma funktionsapp.

Skärmbild av programroutning utan störande ändring i en Durable Functions-distribution.

När du distribuerar en ny version av din app med en icke-bakåtkompatibel ändring kan du öka huvudversionen eller delversionen. Sedan skapar programroutern en ny funktionsapp i Azure, distribuerar till den och dirigerar begäranden för den nya versionen av appen till den. I följande diagram fortsätter orkestreringar på 1.0.1-versionen av appen att köras, men begäranden för 1.1.0-versionen dirigeras till den nya funktionsappen.

Skärmbild av applikationsdirigering för en Durable Functions-utrullning med icke-bakåtkompatibla ändringar.

Routern övervakar statusen för orkestreringar på 1.0.1-versionen och tar bort appar när alla orkestreringar har slutförts.

Inställningar för butiksspårning

Varje funktionsapp bör använda separata schemaläggningsköer, eventuellt i separata lagringskonton. Om du vill köra frågor mot alla orkestreringsinstanser i alla versioner av programmet kan du dela instans- och historiktabeller i dina funktionsappar. Du kan dela tabeller genom att konfigurera trackingStoreConnectionStringName och trackingStoreNamePrefix inställningarna i host.json-filen så att alla använder samma värden.

För mer information, se Hantera instanser i Durable Functions i Azure.

Skärmbild av inställningar för delad spårningslagring i versionerade Durable Functions-appar.

Nästa steg