Share via


Taakhubs in Durable Functions (Azure Functions)

Een taakhub in Durable Functions is een weergave van de huidige status van de toepassing in de opslag, inclusief al het in behandeling zijnde werk. Terwijl een functie-app wordt uitgevoerd, wordt de voortgang van indeling, activiteit en entiteitsfuncties voortdurend opgeslagen in de taakhub. Dit zorgt ervoor dat de toepassing de verwerking kan hervatten waar deze was gebleven, als deze opnieuw moet worden gestart nadat deze om de een of andere reden tijdelijk is gestopt of onderbroken. Bovendien kan de functie-app de rekenwerknemers dynamisch schalen.

Diagram met het concept van de functie-app en het concept van de taakhub.

Conceptueel slaat een taakhub de volgende informatie op:

  • De instantiestatussen van alle indelings- en entiteitsexemplaren.
  • De berichten die moeten worden verwerkt, inclusief
    • alle activiteitsberichten die activiteiten vertegenwoordigen die wachten om te worden uitgevoerd.
    • alle exemplaarberichten die wachten om te worden bezorgd bij instanties.

Het verschil tussen activiteits- en exemplaarberichten is dat activiteitsberichten staatloos zijn en dus overal kunnen worden verwerkt, terwijl exemplaarberichten moeten worden afgeleverd bij een bepaalde stateful instantie (indeling of entiteit), geïdentificeerd door de instantie-id.

Intern kan elke opslagprovider een andere organisatie gebruiken om exemplaarstatussen en berichten weer te geven. Berichten worden bijvoorbeeld opgeslagen in Azure Storage-wachtrijen door de Azure Storage-provider, maar in relationele tabellen door de MSSQL-provider. Deze verschillen maken niet uit wat betreft het ontwerp van de toepassing, maar sommige kunnen van invloed zijn op de prestatiekenmerken. We bespreken deze in de sectie Representatie in opslag hieronder.

Werkitems

De activiteitsberichten en exemplaarberichten in de taakhub vertegenwoordigen het werk dat de functie-app moet verwerken. Terwijl de functie-app wordt uitgevoerd, worden er continu werkitems opgehaald uit de taakhub. Elk werkitem verwerkt een of meer berichten. We onderscheiden twee soorten werkitems:

  • Activiteitswerkitems: voer een activiteitsfunctie uit om een activiteitsbericht te verwerken.
  • Orchestrator-werkitem: voer een orchestrator- of entiteitsfunctie uit om een of meer exemplaarberichten te verwerken.

Werkrollen kunnen meerdere werkitems tegelijk verwerken, afhankelijk van de geconfigureerde gelijktijdigheidslimieten per werkrol.

Zodra een werkrol een werkitem heeft voltooid, worden de effecten weer doorgevoerd in de taakhub. Deze effecten variëren per type functie dat is uitgevoerd:

  • Een voltooide activiteitsfunctie maakt een exemplaarbericht met het resultaat, dat is geadresseerd aan het bovenliggende orchestrator-exemplaar.
  • Een voltooide orchestratorfunctie werkt de indelingsstatus en geschiedenis bij en kan nieuwe berichten maken.
  • Een voltooide entiteitsfunctie werkt de status van de entiteit bij en kan ook nieuwe exemplaarberichten maken.

Voor indelingen vertegenwoordigt elk werkitem één aflevering van de uitvoering van die indeling. Er begint een aflevering wanneer er nieuwe berichten voor de orchestrator moeten worden verwerkt. Een dergelijk bericht kan erop wijzen dat de indeling moet beginnen; of het kan erop wijzen dat een activiteit, entiteitsaanroep, timer of suborchestration is voltooid; of het kan een externe gebeurtenis vertegenwoordigen. Het bericht activeert een werkitem waarmee de orchestrator het resultaat kan verwerken en verder kan gaan met de volgende aflevering. Deze aflevering eindigt wanneer de orchestrator is voltooid of een punt bereikt waarop moet worden gewacht op nieuwe berichten.

Voorbeeld van uitvoering

Overweeg een indeling waarbij twee activiteiten parallel worden gestart en wordt gewacht tot beide activiteiten zijn voltooid:

[FunctionName("Example")]
public static async Task Run([OrchestrationTrigger] IDurableOrchestrationContext context)
{
    Task t1 = context.CallActivityAsync<int>("MyActivity", 1);
    Task t2 = context.CallActivityAsync<int>("MyActivity", 2);
    await Task.WhenAll(t1, t2);
}

Nadat deze indeling is geïnitieerd door een client, wordt deze door de functie-app verwerkt als een reeks werkitems. Elk voltooid werkitem werkt de status van de taakhub bij wanneer deze wordt doorgevoerd. Dit zijn de stappen:

  1. Een client vraagt om een nieuwe indeling te starten met exemplaar-id '123'. Nadat de client deze aanvraag heeft voltooid, bevat de taakhub een tijdelijke aanduiding voor de indelingsstatus en een exemplaarbericht:

    workitems-illustration-step-1

    Het label ExecutionStarted is een van de vele typen geschiedenisevenementen waarmee de verschillende typen berichten en gebeurtenissen worden geïdentificeerd die deelnemen aan de geschiedenis van een indeling.

  2. Een werkrol voert een orchestrator-werkitem uit om het ExecutionStarted bericht te verwerken. Hiermee wordt de orchestratorfunctie aangeroepen die begint met het uitvoeren van de indelingscode. Deze code plant twee activiteiten en stopt met uitvoeren wanneer wordt gewacht op de resultaten. Nadat de werkrol dit werkitem heeft doorgevoerd, bevat de taakhub

    workitems-illustration-step-2

    De runtimestatus is nu Running, er zijn twee nieuwe TaskScheduled berichten toegevoegd en de geschiedenis bevat nu de vijf gebeurtenissen OrchestratorStarted, ExecutionStarted, TaskScheduled, TaskScheduled, OrchestratorCompleted. Deze gebeurtenissen vertegenwoordigen de eerste aflevering van de uitvoering van deze indeling.

  3. Een werkrol voert een activiteitswerkitem uit om een van de TaskScheduled berichten te verwerken. Hiermee wordt de activiteitsfunctie aangeroepen met invoer '2'. Wanneer de activiteitsfunctie is voltooid, wordt er een TaskCompleted bericht met het resultaat gemaakt. Nadat de werkrol dit werkitem heeft doorgevoerd, bevat de taakhub

    workitems-illustration-step-3

  4. Een werkrol voert een orchestrator-werkitem uit om het TaskCompleted bericht te verwerken. Als de indeling nog steeds in het geheugen is opgeslagen, kan de uitvoering worden hervat. Anders wordt de geschiedenis eerst opnieuw afgespeeld om de huidige status van de indeling te herstellen. Vervolgens wordt de indeling voortgezet en wordt het resultaat van de activiteit geleverd. Nadat dit resultaat is ontvangen, wacht de indeling nog steeds op het resultaat van de andere activiteit, waardoor de uitvoering opnieuw wordt gestopt. Nadat de werkrol dit werkitem heeft doorgevoerd, bevat de taakhub

    workitems-illustration-step-4

    De indelingsgeschiedenis bevat nu nog drie gebeurtenissen OrchestratorStarted, TaskCompleted, OrchestratorCompleted. Deze gebeurtenissen vertegenwoordigen de tweede aflevering van de uitvoering van deze indeling.

  5. Een werkrol voert een activiteitswerkitem uit om het resterende TaskScheduled bericht te verwerken. Hiermee wordt de activiteitsfunctie aangeroepen met invoer '1'. Nadat de werkrol dit werkitem heeft doorgevoerd, bevat de taakhub

    workitems-illustration-step-5

  6. Een werkrol voert een ander orchestrator-werkitem uit om het TaskCompleted bericht te verwerken. Nadat u dit tweede resultaat hebt ontvangen, wordt de indeling voltooid. Nadat de werkrol dit werkitem heeft doorgevoerd, bevat de taakhub

    workitems-illustration-step-6

    De runtimestatus is nu Completeden de indelingsgeschiedenis bevat nu nog vier gebeurtenissen OrchestratorStarted, TaskCompleted, ExecutionCompleted, OrchestratorCompleted. Deze gebeurtenissen vertegenwoordigen de derde en laatste aflevering van de uitvoering van deze indeling.

De uiteindelijke geschiedenis voor de uitvoering van deze indeling bevat vervolgens de 12 gebeurtenissen , , , , TaskScheduled, OrchestratorCompletedOrchestratorStarted, TaskCompleted, OrchestratorCompleted, OrchestratorStarted, TaskCompleted, , ExecutionCompleted. OrchestratorCompletedTaskScheduledExecutionStartedOrchestratorStarted

Notitie

De weergegeven planning is niet de enige: er zijn veel enigszins verschillende schema's mogelijk. Als de tweede activiteit bijvoorbeeld eerder is voltooid, kunnen beide TaskCompleted exemplaarberichten worden verwerkt door één werkitem. In dat geval is de uitvoeringsgeschiedenis iets korter, omdat er slechts twee afleveringen zijn en deze de volgende 10 gebeurtenissen bevat: , , , , TaskScheduled, OrchestratorCompleted, , OrchestratorStarted, , TaskCompleted, TaskCompleted, , ExecutionCompleted, . OrchestratorCompletedTaskScheduledExecutionStartedOrchestratorStarted

Beheer van taakhubs

Laten we nu eens kijken hoe taakhubs worden gemaakt of verwijderd, hoe u taakhubs correct kunt gebruiken bij het uitvoeren van meerdere functie-apps en hoe de inhoud van taakhubs kan worden gecontroleerd.

Maken en verwijderen

Er wordt automatisch een lege taakhub met alle vereiste resources in de opslag gemaakt wanneer de eerste keer een functie-app wordt gestart.

Als u de standaard Azure Storage-provider gebruikt, is er geen extra configuratie vereist. Volg anders de instructies voor het configureren van opslagproviders om ervoor te zorgen dat de opslagprovider de opslagresources die nodig zijn voor de taakhub correct kan inrichten en openen.

Notitie

De taakhub wordt niet automatisch verwijderd wanneer u de functie-app stopt of verwijdert. U moet de taakhub, de inhoud ervan of het bijbehorende opslagaccount handmatig verwijderen als u deze gegevens niet meer wilt bewaren.

Tip

In een ontwikkelingsscenario moet u mogelijk vaak opnieuw opstarten vanuit een schone status. Als u dit snel wilt doen, hoeft u alleen de naam van de geconfigureerde taakhub te wijzigen. Hierdoor wordt het maken van een nieuwe, lege taakhub afgedwongen wanneer u de toepassing opnieuw start. Houd er rekening mee dat de oude gegevens in dit geval niet worden verwijderd.

Meerdere functie-apps

Als meerdere functie-apps een opslagaccount delen, moet elke functie-app worden geconfigureerd met een afzonderlijke taakhubnaam. Deze vereiste geldt ook voor staging-sites: elke staging-site moet worden geconfigureerd met een unieke taakhubnaam. Eén opslagaccount kan meerdere taakhubs bevatten. Deze beperking geldt over het algemeen ook voor andere opslagproviders.

In het volgende diagram ziet u één taakhub per functie-app in gedeelde en toegewezen Azure Storage-accounts.

Diagram met gedeelde en toegewezen opslagaccounts.

Notitie

De uitzondering op de taakhub-regel voor delen is als u uw app configureert voor herstel na een regionaal noodgeval. Zie het artikel herstel na noodgeval en geo-distributie voor meer informatie.

Inhoudsinspectie

Er zijn verschillende algemene manieren om de inhoud van een taakhub te controleren:

  1. Binnen een functie-app biedt het clientobject methoden om query's uit te voeren op het exemplaararchief. Zie het artikel Exemplaarbeheer voor meer informatie over welke typen query's worden ondersteund.
  2. Op dezelfde manier biedt de HTTP-API REST-aanvragen voor het opvragen van de status van indelingen en entiteiten. Zie de HTTP API-verwijzing voor meer informatie.
  3. Het hulpprogramma Durable Functions Monitor kan taakhubs inspecteren en biedt verschillende opties voor visuele weergave.

Voor sommige opslagproviders is het ook mogelijk om de taakhub te inspecteren door rechtstreeks naar de onderliggende opslag te gaan:

  • Als u de Azure Storage-provider gebruikt, worden de statussen van het exemplaar opgeslagen in de exemplaartabel en de geschiedenistabel, die kunnen worden geïnspecteerd met hulpprogramma's zoals Azure Storage Explorer.
  • Als u de MSSQL-opslagprovider gebruikt, kunnen SQL-query's en hulpprogramma's worden gebruikt om de inhoud van de taakhub in de database te inspecteren.

Weergave in opslag

Elke opslagprovider gebruikt een andere interne organisatie om taakhubs in de opslag te vertegenwoordigen. Kennis van deze organisatie is niet vereist, maar kan nuttig zijn bij het oplossen van problemen met een functie-app of bij het garanderen van prestaties, schaalbaarheid of kostendoelen. Daarom leggen we voor elke opslagprovider kort uit hoe de gegevens in de opslag zijn georganiseerd. Zie de Durable Functions opslagproviders voor meer informatie over de verschillende opties voor opslagproviders en hoe deze zich verhouden.

Azure Storage-provider

De Azure Storage-provider vertegenwoordigt de taakhub in de opslag met behulp van de volgende onderdelen:

  • In twee Azure-tabellen worden de statussen van het exemplaar opgeslagen.
  • In één Azure-wachtrij worden de activiteitsberichten opgeslagen.
  • Een of meer Azure Queues slaan de exemplaarberichten op. Elk van deze zogenaamde beheerwachtrijen vertegenwoordigt een partitie waaraan een subset van alle exemplaarberichten wordt toegewezen op basis van de hash van de exemplaar-id.
  • Een paar extra blobcontainers die worden gebruikt voor lease-blobs en/of grote berichten.

Een taakhub met de naam xyz met PartitionCount = 4 bevat bijvoorbeeld de volgende wachtrijen en tabellen:

Diagram van de opslagopslagorganisatie van de Azure Storage-provider voor 4 besturingswachtrijen.

Vervolgens beschrijven we deze onderdelen en de rol die ze spelen in meer detail.

Zie de documentatie van de Azure Storage-provider voor meer informatie over hoe taakhubs worden vertegenwoordigd door de Azure Storage-provider .

Netherite-opslagprovider

Netherite partitioneert alle status van de taakhub in een opgegeven aantal partities. In opslag worden de volgende resources gebruikt:

  • Eén Azure Storage-blobcontainer die alle blobs bevat, gegroepeerd op partitie.
  • Eén Azure-tabel met gepubliceerde metrische gegevens over de partities.
  • Een Azure Event Hubs naamruimte voor het leveren van berichten tussen partities.

Een taakhub met de naam mytaskhub met PartitionCount = 32 wordt bijvoorbeeld als volgt weergegeven in de opslag:

Diagram van de Netherite-opslagorganisatie voor 32 partities.

Notitie

De status van de taakhub wordt opgeslagen in de x-storage blobcontainer. De DurableTaskPartitions tabel en de EventHubs-naamruimte bevatten redundante gegevens: als de inhoud verloren gaat, kunnen deze automatisch worden hersteld. Daarom is het niet nodig om de Azure Event Hubs naamruimte te configureren om berichten na de standaardverlooptijd te bewaren.

Netherite maakt gebruik van een mechanisme voor gebeurtenisbronnen, gebaseerd op een logboek en controlepunten, om de huidige status van een partitie weer te geven. Zowel blok-blobs als pagina-blobs worden gebruikt. Het is niet mogelijk om deze indeling rechtstreeks vanuit de opslag te lezen, dus de functie-app moet worden uitgevoerd bij het uitvoeren van query's op de instantieopslag.

Zie Task Hub-informatie voor de Netherite-opslagprovider voor meer informatie over taakhubs voor de Netherite-opslagprovider.

MSSQL-opslagprovider

Alle gegevens van de taakhub worden opgeslagen in één relationele database met behulp van verschillende tabellen:

  • In de dt.Instances tabellen en dt.History worden de statussen van het exemplaar opgeslagen.
  • In dt.NewEvents de tabel worden de exemplaarberichten opgeslagen.
  • De dt.NewTasks activiteitsberichten worden opgeslagen in de tabel.

Diagram met MSSQL-opslagorganisatie.

Als u wilt dat meerdere taakhubs naast elkaar in dezelfde database kunnen bestaan, bevat elke tabel een TaskHub kolom als onderdeel van de primaire sleutel. In tegenstelling tot de andere twee providers heeft de MSSQL-provider geen concept van partities.

Zie Task Hub information for the Microsoft SQL (MSSQL)-opslagprovider voor meer informatie over taakhubs voor de MSSQL-opslagprovider.

Namen van taakhubs

Taakhubs worden aangeduid met een naam die moet voldoen aan deze regels:

  • Bevat alleen alfanumerieke tekens
  • Begint met een letter
  • Heeft een minimale lengte van 3 tekens, maximale lengte van 45 tekens

De naam van de taakhub wordt gedeclareerd in het bestand host.json , zoals wordt weergegeven in het volgende voorbeeld:

host.json (Functions 2.0)

{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "hubName": "MyTaskHub"
    }
  }
}

host.json (Functions 1.x)

{
  "durableTask": {
    "hubName": "MyTaskHub"
  }
}

Taakhubs kunnen ook worden geconfigureerd met behulp van app-instellingen, zoals wordt weergegeven in het volgende host.json voorbeeldbestand:

host.json (Functions 1.0)

{
  "durableTask": {
    "hubName": "%MyTaskHub%"
  }
}

host.json (Functions 2.0)

{
  "version": "2.0",
  "extensions": {
    "durableTask": {
      "hubName": "%MyTaskHub%"
    }
  }
}

De naam van de taakhub wordt ingesteld op de waarde van de MyTaskHub app-instelling. Hieronder ziet local.settings.json u hoe u de MyTaskHub instelling definieert als samplehubname:

{
  "IsEncrypted": false,
  "Values": {
    "MyTaskHub" : "samplehubname"
  }
}

Notitie

Wanneer u implementatiesites gebruikt, is het een best practice om de naam van de taakhub te configureren met behulp van app-instellingen. Als u ervoor wilt zorgen dat een bepaalde site altijd gebruikmaakt van een bepaalde taakhub, gebruikt u de app-instellingen 'site-sticky'.

Naast host.json kunnen namen van taakhubs ook worden geconfigureerd in metagegevens van orchestration-clientbinding . Dit is handig als u toegang nodig hebt tot indelingen of entiteiten die zich in een afzonderlijke functie-app bevinden. De volgende code laat zien hoe u een functie schrijft die gebruikmaakt van de orchestration-clientbinding om te werken met een taakhub die is geconfigureerd als een app-instelling:

[FunctionName("HttpStart")]
public static async Task<HttpResponseMessage> Run(
    [HttpTrigger(AuthorizationLevel.Function, methods: "post", Route = "orchestrators/{functionName}")] HttpRequestMessage req,
    [DurableClient(TaskHub = "%MyTaskHub%")] IDurableOrchestrationClient starter,
    string functionName,
    ILogger log)
{
    // Function input comes from the request content.
    object eventData = await req.Content.ReadAsAsync<object>();
    string instanceId = await starter.StartNewAsync(functionName, eventData);

    log.LogInformation($"Started orchestration with ID = '{instanceId}'.");

    return starter.CreateCheckStatusResponse(req, instanceId);
}

Notitie

Het vorige voorbeeld is voor Durable Functions 2.x. Voor Durable Functions 1.x moet u in plaats van IDurableOrchestrationContextgebruikenDurableOrchestrationContext. Zie het artikel Durable Functions versies voor meer informatie over de verschillen tussen versies.

Notitie

Het configureren van taakhubnamen in metagegevens van clientbindingen is alleen nodig wanneer u één functie-app gebruikt voor toegang tot indelingen en entiteiten in een andere functie-app. Als de clientfuncties zijn gedefinieerd in dezelfde functie-app als de indelingen en entiteiten, moet u voorkomen dat u taakhubnamen opgeeft in de metagegevens van de binding. Standaard krijgen alle clientbindingen hun taakhubmetagegevens uit de host.json-instellingen .

Namen van taakhubs moeten beginnen met een letter en mogen alleen letters en cijfers bevatten. Als u dit niet opgeeft, wordt een standaardnaam voor de taakhub gebruikt, zoals wordt weergegeven in de volgende tabel:

Versie van duurzame extensie Standaardnaam van taakhub
2.x Bij implementatie in Azure wordt de naam van de taakhub afgeleid van de naam van de functie-app. Wanneer u buiten Azure wordt uitgevoerd, is TestHubNamede standaardnaam van de taakhub .
1.x De standaardnaam van de taakhub voor alle omgevingen is DurableFunctionsHub.

Zie het artikel Durable Functions versies voor meer informatie over de verschillen tussen extensieversies.

Notitie

De naam is wat de ene taakhub van de andere onderscheidt wanneer een gedeeld opslagaccount meerdere taakhubs bevat. Als u meerdere functie-apps hebt die een gedeeld opslagaccount delen, moet u expliciet verschillende namen configureren voor elke taakhub in de host.json-bestanden . Anders concurreren de meerdere functie-apps met elkaar om berichten, wat kan leiden tot niet-gedefinieerd gedrag, waaronder indelingen die onverwacht 'vastlopen' in de Pending status of Running .

Volgende stappen