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.
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:
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:
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.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 taakhubDe runtimestatus is nu
Running
, er zijn twee nieuweTaskScheduled
berichten toegevoegd en de geschiedenis bevat nu de vijf gebeurtenissenOrchestratorStarted
,ExecutionStarted
,TaskScheduled
,TaskScheduled
,OrchestratorCompleted
. Deze gebeurtenissen vertegenwoordigen de eerste aflevering van de uitvoering van deze indeling.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 eenTaskCompleted
bericht met het resultaat gemaakt. Nadat de werkrol dit werkitem heeft doorgevoerd, bevat de taakhubEen 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 taakhubDe indelingsgeschiedenis bevat nu nog drie gebeurtenissen
OrchestratorStarted
,TaskCompleted
,OrchestratorCompleted
. Deze gebeurtenissen vertegenwoordigen de tweede aflevering van de uitvoering van deze indeling.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 taakhubEen 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 taakhubDe runtimestatus is nu
Completed
en de indelingsgeschiedenis bevat nu nog vier gebeurtenissenOrchestratorStarted
,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
, OrchestratorCompleted
OrchestratorStarted
, TaskCompleted
, OrchestratorCompleted
, OrchestratorStarted
, TaskCompleted
, , ExecutionCompleted
. OrchestratorCompleted
TaskScheduled
ExecutionStarted
OrchestratorStarted
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
, . OrchestratorCompleted
TaskScheduled
ExecutionStarted
OrchestratorStarted
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.
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:
- 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.
- 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.
- 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:
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:
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.
MSSQL-opslagprovider
Alle gegevens van de taakhub worden opgeslagen in één relationele database met behulp van verschillende tabellen:
- In de
dt.Instances
tabellen endt.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.
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 IDurableOrchestrationContext
gebruikenDurableOrchestrationContext
. 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 TestHubName de 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
.