Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
VAN TOEPASSING OP: NoSQL
De wijzigingenfeedprocessor maakt deel uit van de AZURE Cosmos DB .NET V3 - en Java V4-SDK's , waarmee het proces van het lezen van de wijzigingenfeed wordt vereenvoudigd en de gebeurtenisverwerking effectief over meerdere consumenten wordt gedistribueerd.
Het belangrijkste voordeel van het gebruik van de wijzigingenfeedprocessor is het fouttolerante ontwerp, dat zorgt voor een ten minste eenmaal uitgevoerde levering van alle gebeurtenissen in de wijzigingenfeed.
Ondersteunde SDK's
| .NET V3 | Java | Node.JS | Python |
|---|---|---|---|
| ✓ | ✓ | ✕ | ✕ |
Onderdelen van de wijzigingenfeedprocessor
De change feed processor heeft vier hoofdcomponenten:
De bewaakte container: de bewaakte container bevat de gegevens waaruit de wijzigingenfeed wordt gegenereerd. Eventuele toevoegingen en updates van de bewaakte container worden weergegeven in de wijzigingenfeed van de container.
De leasecontainer: De leasecontainer dient als statusbewaring en coördineert de verwerking van de veranderingsstroom voor meerdere werknemers. De leasecontainer kan worden opgeslagen in hetzelfde account als de bewaakte container of in een afzonderlijk account.
De computerinstantie: Een computerinstantie fungeert als host voor de veranderingsfeedprocessor om naar wijzigingen te luisteren. Afhankelijk van het platform kan het worden vertegenwoordigd door een virtuele machine (VM), een Kubernetes-pod, een Azure-app Service-exemplaar of een werkelijke fysieke machine. Het rekenproces heeft een unieke id die de naam van het exemplaar in dit artikel wordt genoemd.
De delegeerder: De delegeerder is de code die definieert wat u, de ontwikkelaar, wilt doen met elke batch veranderingen die de veranderingenfeedprocessor leest.
Laten we eens kijken naar een voorbeeld in het volgende diagram voor meer informatie over hoe deze vier elementen van de wijzigingenfeedprocessor samenwerken. De bewaakte container slaat items op en gebruikt 'Plaats' als partitiesleutel. De partitiesleutelwaarden worden gedistribueerd in bereiken (elk bereik vertegenwoordigt een fysieke partitie) die items bevatten.
Het diagram toont twee rekeninstanties en de wijzigingenfeedprocessor wijst verschillende bereiken toe aan elk exemplaar om de rekendistributie te maximaliseren. Elk exemplaar heeft een andere, unieke naam.
Elk bereik wordt parallel gelezen. De voortgang van een bereik wordt afzonderlijk bijgehouden van andere bereiken in de leasecontainer via een leasedocument . De combinatie van de leases vertegenwoordigt de huidige status van de wijzigingsfeedprocessor.
De wijzigingenfeedprocessor implementeren
De processor van de wijzigingenfeed in .NET is beschikbaar voor de nieuwste versiemodus en alle versies en verwijdermodus. Alle versies en verwijderingsmodus is in preview en wordt ondersteund voor de wijzigingenfeedprocessor vanaf versie 3.40.0-preview.0. Het toegangspunt voor beide modi is altijd de bewaakte container.
Als u wilt lezen met de nieuwste versiemodus, roept Containeru in een GetChangeFeedProcessorBuilder exemplaar het volgende aan:
/// <summary>
/// Start the Change Feed Processor to listen for changes and process them with the HandleChangesAsync implementation.
/// </summary>
private static async Task<ChangeFeedProcessor> StartChangeFeedProcessorAsync(
CosmosClient cosmosClient,
IConfiguration configuration)
{
string databaseName = configuration["SourceDatabaseName"];
string sourceContainerName = configuration["SourceContainerName"];
string leaseContainerName = configuration["LeasesContainerName"];
Container leaseContainer = cosmosClient.GetContainer(databaseName, leaseContainerName);
ChangeFeedProcessor changeFeedProcessor = cosmosClient.GetContainer(databaseName, sourceContainerName)
.GetChangeFeedProcessorBuilder<ToDoItem>(processorName: "changeFeedSample", onChangesDelegate: HandleChangesAsync)
.WithInstanceName("consoleHost")
.WithLeaseContainer(leaseContainer)
.Build();
Console.WriteLine("Starting Change Feed Processor...");
await changeFeedProcessor.StartAsync();
Console.WriteLine("Change Feed Processor started.");
return changeFeedProcessor;
}
Als u wilt lezen in alle versies en in de verwijdermodus, roep GetChangeFeedProcessorBuilderWithAllVersionsAndDeletes aan vanuit het Container exemplaar.
Container leaseContainer = client.GetContainer(Program.databaseName, Program.leasesContainer);
Container monitoredContainer = client.GetContainer(Program.databaseName, containerName);
ChangeFeedProcessor changeFeedProcessor = monitoredContainer
.GetChangeFeedProcessorBuilderWithAllVersionsAndDeletes<ToDoItem>(processorName: "changeFeedBasic", onChangesDelegate: Program.HandleChangesAsync)
.WithInstanceName("consoleHost")
.WithLeaseContainer(leaseContainer)
.Build();
Voor beide modi is de eerste parameter een afzonderlijke naam die het doel van deze processor beschrijft. De tweede naam is de gedelegeerde-implementatie die wijzigingen verwerkt.
Hier volgt een voorbeeld van een gemachtigde voor de nieuwste versiemodus:
/// <summary>
/// The delegate receives batches of changes as they are generated in the change feed and can process them.
/// </summary>
static async Task HandleChangesAsync(
ChangeFeedProcessorContext context,
IReadOnlyCollection<ToDoItem> changes,
CancellationToken cancellationToken)
{
Console.WriteLine($"Started handling changes for lease {context.LeaseToken}...");
Console.WriteLine($"Change Feed request consumed {context.Headers.RequestCharge} RU.");
// SessionToken if needed to enforce Session consistency on another client instance
Console.WriteLine($"SessionToken ${context.Headers.Session}");
// We may want to track any operation's Diagnostics that took longer than some threshold
if (context.Diagnostics.GetClientElapsedTime() > TimeSpan.FromSeconds(1))
{
Console.WriteLine($"Change Feed request took longer than expected. Diagnostics:" + context.Diagnostics.ToString());
}
foreach (ToDoItem item in changes)
{
Console.WriteLine($"Detected operation for item with id {item.id}, created at {item.creationTime}.");
// Simulate some asynchronous operation
await Task.Delay(10);
}
Console.WriteLine("Finished handling changes.");
}
Hier volgt een voorbeeld van een gemachtigde voor alle versies en de verwijdermodus:
static async Task HandleChangesAsync(ChangeFeedProcessorContext context, IReadOnlyCollection<ChangeFeedItem<ToDoItem>> changes, CancellationToken cancellationToken)
{
Console.WriteLine($"Started handling changes for lease {context.LeaseToken}...");
Console.WriteLine($"Change Feed request consumed {context.Headers.RequestCharge} RU.");
// SessionToken if needed to enforce Session consistency on another client instance
Console.WriteLine($"SessionToken ${context.Headers.Session}");
// We may want to track any operation's Diagnostics that took longer than some threshold
if (context.Diagnostics.GetClientElapsedTime() > TimeSpan.FromSeconds(1))
{
Console.WriteLine($"Change Feed request took longer than expected. Diagnostics:" + context.Diagnostics.ToString());
}
foreach (ChangeFeedItem<ToDoItem> item in changes)
{
if (item.Metadata.OperationType == ChangeFeedOperationType.Delete)
{
Console.WriteLine($"\tDetected {item.Metadata.OperationType} operation for item.");
}
else
{
Console.WriteLine($"\tDetected {item.Metadata.OperationType} operation for item with id {item.Current.id}.");
}
// Simulate work
await Task.Delay(1);
}
}
Daarna definieert u de naam van het rekenproces of de unieke id met behulp van WithInstanceName. De naam van het rekenproces moet uniek en verschillend zijn voor elk rekenproces dat u implementeert. U stelt de container in om de leasestatus te behouden met behulp van WithLeaseContainer.
Het aanroepen van Build geeft u het processorexemplaar dat u kunt starten door StartAsync aan te roepen.
Belangrijk
Vermijd asynchrone verwerking in gedelegeerde methoden: wanneer u asynchrone API's binnen uw handleChanges() gedelegeerde methode gebruikt, moet u er rekening mee houden dat de wijzigingen-feedverwerker de lease kan vastleggen voordat alle asynchrone bewerkingen zijn afgerond. Dit kan leiden tot gemiste gebeurtenissen als de toepassing problemen ondervindt tijdens het herstel. Overweeg synchrone verwerking te gebruiken of de juiste voltooiingstracering te implementeren voordat de gedelegeerde kan terugkeren.
Notitie
De voorgaande codefragmenten worden genomen uit voorbeelden in GitHub. U kunt het voorbeeld ophalen voor de laatste versiemodus of de modus voor alle versies en verwijderingen.
Verwerkingslevenscyclus
De normale levenscyclus van een host-exemplaar is:
- Lees de wijzigingenfeed.
- Als er geen wijzigingen zijn, wacht een vooraf gedefinieerde hoeveelheid tijd (aanpasbaar met behulp van
WithPollIntervalin de Builder) en ga naar stap 1. - Als er wijzigingen zijn, stuurt u deze naar de gemachtigde.
- Wanneer de gemachtigde succesvol klaar is met het verwerken van de wijzigingen, werkt men het leaseregister bij met het laatst verwerkte tijdstip en gaat men naar stap 1.
Foutafhandeling
De wijzigingenfeedprocessor is bestand tegen fouten in gebruikerscode. Als uw gedelegeerde-implementatie een niet-verwerkte uitzondering heeft (stap 4), wordt de thread die die bepaalde batch wijzigingen verwerkt, gestopt en wordt er uiteindelijk een nieuwe thread gemaakt. De nieuwe thread controleert het nieuwste tijdstip dat de verhuurwinkel heeft opgeslagen voor dat bereik van partitiesleutelwaarden. De nieuwe thread start daar opnieuw op, waarmee hetzelfde pakket wijzigingen naar de gemachtigde wordt verzonden. Dit gedrag wordt voortgezet totdat de gedelegeerde de wijzigingen correct verwerkt. Dit is de reden waarom de wijzigingenfeedverwerker ten minste één keer een garantie heeft.
Notitie
In slechts één scenario wordt een batch wijzigingen niet opnieuw geprobeerd. Als de fout optreedt bij de eerste uitvoering van de afgevaardigde, heeft de leasestore geen eerder opgeslagen status die kan worden gebruikt voor de nieuwe poging. In dergelijke gevallen wordt voor de nieuwe poging de eerste beginconfiguratie gebruikt, die de laatste batch al dan niet bevat.
Als u wilt voorkomen dat uw wijzigingenfeedprocessor voortdurend blijft hangen bij het proberen opnieuw te verwerken van dezelfde batch wijzigingen, moet u logica toevoegen aan de code die gedelegeerd is om bij uitzondering documenten naar een wachtrij met foutberichten te schrijven. Dit ontwerp zorgt ervoor dat u niet-verwerkte wijzigingen kunt bijhouden terwijl u toekomstige wijzigingen nog steeds kunt blijven verwerken. De wachtrij met foutberichten kan een andere Azure Cosmos DB-container zijn. Het exacte gegevensarchief maakt niet uit. U wilt gewoon dat de niet-verwerkte wijzigingen behouden blijven.
U kunt de wijzigingsfeedschatter ook gebruiken om de voortgang van de exemplaren van de wijzigingenfeedprocessor te controleren terwijl ze de wijzigingenfeed lezen, of u kunt levenscyclusmeldingen gebruiken om onderliggende fouten te detecteren.
Zorg ervoor dat de time-out van de clientnetwerkaanvraag langer is dan de time-out aan de serverzijde om te voorkomen dat time-outs niet overeenkomen die kunnen leiden tot verwerkingsfouten. De standaard time-out aan de serverzijde is vijf seconden. Houd fouten gerelateerd aan time-outs in de gaten en pas de configuraties dienovereenkomstig aan.
Meldingen over levenscyclus
U kunt de wijzigingenfeedprocessor verbinden met elke relevante gebeurtenis in de levenscyclus. U kunt ervoor kiezen om een of meer meldingen te ontvangen. De aanbeveling is om ten minste de foutmelding te registreren:
- Registreer een handler voor
WithLeaseAcquireNotificationom een melding te krijgen wanneer de huidige host een lease verkrijgt voor verwerking. - Registreer een handler om
WithLeaseReleaseNotificationop de hoogte te worden gebracht wanneer de huidige host een lease vrijgeeft en stopt met verwerken ervan. - Registreer een handler voor
WithErrorNotificationom op de hoogte te worden gebracht wanneer de huidige host tijdens de verwerking een uitzonderingssituatie tegenkomt. U moet kunnen onderscheiden of de bron delegeren van de gebruiker is (een niet-verwerkte uitzondering) of een fout die de processor tegenkomt wanneer deze toegang probeert te krijgen tot de bewaakte container (bijvoorbeeld netwerkproblemen).
Meldingen over levenscyclus zijn beschikbaar in beide modi voor wijzigingenfeeds. Hier volgt een voorbeeld van levenscyclusmeldingen in de nieuwste versiemodus:
Container.ChangeFeedMonitorLeaseAcquireDelegate onLeaseAcquiredAsync = (string leaseToken) =>
{
Console.WriteLine($"Lease {leaseToken} is acquired and will start processing");
return Task.CompletedTask;
};
Container.ChangeFeedMonitorLeaseReleaseDelegate onLeaseReleaseAsync = (string leaseToken) =>
{
Console.WriteLine($"Lease {leaseToken} is released and processing is stopped");
return Task.CompletedTask;
};
Container.ChangeFeedMonitorErrorDelegate onErrorAsync = (string LeaseToken, Exception exception) =>
{
if (exception is ChangeFeedProcessorUserException userException)
{
Console.WriteLine($"Lease {LeaseToken} processing failed with unhandled exception from user delegate {userException.InnerException}");
}
else
{
Console.WriteLine($"Lease {LeaseToken} failed with {exception}");
}
return Task.CompletedTask;
};
ChangeFeedProcessor changeFeedProcessor = monitoredContainer
.GetChangeFeedProcessorBuilder<ToDoItem>("changeFeedNotifications", handleChanges)
.WithLeaseAcquireNotification(onLeaseAcquiredAsync)
.WithLeaseReleaseNotification(onLeaseReleaseAsync)
.WithErrorNotification(onErrorAsync)
.WithInstanceName("consoleHost")
.WithLeaseContainer(leaseContainer)
.Build();
Implementatie-eenheid
Eén implementatie-eenheid voor de wijzigingsfeedprocessor bestaat uit een of meer rekeninstanties met dezelfde waarde voor processorName en dezelfde leasecontainerconfiguratie, maar verschillende exemplaarnamen. U kunt veel implementatie-eenheden hebben waarin elke eenheid een andere bedrijfsstroom heeft voor de wijzigingen en elke implementatie-eenheid bestaat uit een of meer exemplaren.
U hebt bijvoorbeeld één implementatie-eenheid die een externe API activeert telkens wanneer er een wijziging in uw container is. Een andere implementatie-eenheid kan gegevens in realtime verplaatsen telkens wanneer er een wijziging is. Wanneer er een wijziging in uw bewaakte container plaatsvindt, worden al uw implementatie-eenheden op de hoogte gebracht.
Dynamische schaalbaarheid
Zoals eerder vermeld, kunt u binnen een implementatie-eenheid een of meer rekeninstanties hebben. Als u wilt profiteren van de rekendistributie binnen de implementatie-eenheid, zijn de enige belangrijke vereisten:
- Alle instanties moeten dezelfde configuratie voor de leasecontainer hebben.
- Alle exemplaren moeten dezelfde waarde hebben voor
processorName. - Elk exemplaar moet een andere naam hebben (
WithInstanceName).
Als deze drie voorwaarden van toepassing zijn, distribueert de wijzigingenfeed-processor alle leases die zich in de leasecontainer bevinden over alle actieve exemplaren van die implementatie-eenheid, en wordt de berekening geparalleliseerd met behulp van een algoritme voor gelijke distributie. Een lease is op elk moment eigendom van één instantie, dus het aantal instanties mag niet groter zijn dan het aantal leases.
Het aantal gevallen kan toenemen en afnemen. De wijzigingenfeedprocessor past de belasting dynamisch aan door deze dienovereenkomstig te distribueren.
Bovendien kan de wijzigingenfeedprocessor dynamisch de schaal van een container aanpassen als de doorvoer of opslag van de container toeneemt. Wanneer uw container groeit, behandelt de change feed-verwerker het scenario transparant door de leases dynamisch uit te breiden en de nieuwe leases tussen bestaande instanties te verdelen.
Begintijd
Standaard wordt, wanneer een verwerker van een wijzigingenfeed voor het eerst wordt gestart, de leasecontainer geïnitialiseerd en begint de levenscyclus van de verwerking. Wijzigingen die zijn aangebracht in de bewaakte container voordat de verwerker van de wijzigingenfeed voor het eerst wordt geïnitialiseerd, worden niet gedetecteerd.
Lezen vanaf een vorige datum en tijd
Het is mogelijk om de change feed-processor te initialiseren om veranderingen te lezen vanaf een specifieke datum en tijd door een exemplaar van DateTime aan de WithStartTime builder-extensie door te geven.
Container leaseContainer = client.GetContainer(databaseId, Program.leasesContainer);
Container monitoredContainer = client.GetContainer(databaseId, Program.monitoredContainer);
ChangeFeedProcessor changeFeedProcessor = monitoredContainer
.GetChangeFeedProcessorBuilder<ToDoItem>("changeFeedTime", Program.HandleChangesAsync)
.WithInstanceName("consoleHost")
.WithLeaseContainer(leaseContainer)
.WithStartTime(particularPointInTime)
.Build();
De wijzigingenfeedverwerker wordt geïnitialiseerd voor die specifieke datum en tijd en begint de wijzigingen te lezen die daarna zijn aangebracht.
Lezen vanaf het begin
In andere scenario's, zoals in gegevensmigraties of als u de hele geschiedenis van een container analyseert, moet u de wijzigingenfeed lezen vanaf het begin van de levensduur van die container. U kunt de builder extensie gebruiken WithStartTime, maar DateTime.MinValue.ToUniversalTime() doorgeven, waarmee de UTC-weergave van de minimale DateTime waarde wordt gegenereerd, zoals in dit voorbeeld:
Container leaseContainer = client.GetContainer(databaseId, Program.leasesContainer);
Container monitoredContainer = client.GetContainer(databaseId, Program.monitoredContainer);
ChangeFeedProcessor changeFeedProcessor = monitoredContainer
.GetChangeFeedProcessorBuilder<ToDoItem>("changeFeedBeginning", Program.HandleChangesAsync)
.WithInstanceName("consoleHost")
.WithLeaseContainer(leaseContainer)
.WithStartTime(DateTime.MinValue.ToUniversalTime())
.Build();
De processor van de wijzigingenfeed wordt geïnitialiseerd en begint met het lezen van wijzigingen vanaf het begin van de levensduur van de container.
Notitie
Deze aanpassingsopties werken alleen om het beginnend punt in de tijd van de wijzigingsfeedprocessor in te stellen. Nadat de leasecontainer voor het eerst is geïnitialiseerd, heeft het wijzigen van deze opties geen effect.
Het aanpassen van het beginpunt is alleen beschikbaar voor de nieuwste versie van de wijzigingenfeedmodus. Wanneer u de modus voor alle versies en verwijderingen gebruikt, moet u beginnen met lezen vanaf het moment dat de processor wordt gestart, of hervat vanuit een eerdere lease-status die zich binnen de retentieperiode voor doorlopende back-up van uw account bevindt.
Veranderingsfeed en geconfigureerde doorvoer
Leesbewerkingen voor wijzigingsfeeds van de bewaakte container verbruiken aanvraageenheden. Zorg ervoor dat uw bewaakte container geen throttling ervaart. Door drosseling worden bij uw verwerkers vertragingen toegevoegd bij het ontvangen van wijzigingsfeed-gebeurtenissen.
Operaties op de leasecontainer (bijwerken en handhaven van de status) verbruiken aanvraageenheden. Hoe hoger het aantal exemplaren dat dezelfde leasecontainer gebruikt, hoe hoger het potentiële gebruik van aanvraageenheden. Zorg ervoor dat uw leasecontainer geen beperking ondervindt. Door throttling worden vertragingen toegevoegd bij het ontvangen van wijzigingenfeed-events. Drosseling kan zelfs de verwerking volledig beëindigen.
De leasecontainer delen
U kunt een leasecontainer delen over meerdere implementatie-eenheden. In een gedeelde leasecontainer luistert elke implementatie-eenheid naar een andere bewaakte container of heeft een andere waarde voor processorName. In deze configuratie onderhoudt elke implementatie-eenheid een onafhankelijke status op de leasecontainer. Controleer het verbruik van de aanvraageenheid voor een leasecontainer om ervoor te zorgen dat de ingerichte doorvoer voldoende is voor alle implementatie-eenheden.
Geavanceerde leaseconfiguratie
Drie sleutelconfiguraties kunnen van invloed zijn op de werking van de wijzigingenfeedprocessor. Elke configuratie is van invloed op het verbruik van de aanvraageenheid in de leasecontainer. U kunt een van deze configuraties instellen wanneer u de change feed-processor maakt, maar u moet ze zorgvuldig gebruiken:
- Lease verwerving: standaard elke 17 seconden. Een host controleert regelmatig de toestand van de leasestore en overweegt leases te verkrijgen als onderdeel van het dynamische schaalproces. Dit proces wordt uitgevoerd door een query uit te voeren op de leasecontainer. Door deze waarde te verminderen, wordt herverdeling en het verkrijgen van leases sneller, maar wordt het verbruik van aanvraageenheden voor de leasecontainer verhoogd.
- Verlooptijd van lease: standaard 60 seconden. Definieert de maximale hoeveelheid tijd die een lease kan bestaan zonder verlengingsactiviteit voordat deze wordt verkregen door een andere host. Wanneer een host vastloopt, worden de leases waarvan deze eigenaar is, opgehaald door andere hosts na deze periode plus het geconfigureerde verlengingsinterval. Als u deze waarde vermindert, wordt het herstellen na een crash van de host sneller, maar de verloopwaarde mag nooit lager zijn dan het vernieuwingsinterval.
- Verlenging van lease: standaard om de 13 seconden. Een host die eigenaar is van een lease, verlengt de lease periodiek, zelfs als er geen nieuwe wijzigingen zijn die hoeven te worden doorgevoerd. Dit proces wordt uitgevoerd door een 'Replace' uit te voeren op de lease. Als u deze waarde verlaagt, wordt de tijd verlaagd die nodig is om leases te detecteren die verloren gaan door een host die vastloopt, maar het verhoogt het verbruik van aanvraageenheden voor de leasecontainer.
Waar kan ik de wijzigingenfeedprocessor hosten?
De wijzigingenfeedprocessor kan worden gehost in elk platform dat langlopende processen of taken ondersteunt. Hieronder volgen een aantal voorbeelden:
- Een proces in een exemplaar van Azure Virtual Machines
- Een achtergrondtaak in Azure Kubernetes Service
- Een serverloze functie in Azure Functions
- Een ASP.NET gehoste service
Hoewel de wijzigingsfeedprocessor in tijdelijke omgevingen kan worden uitgevoerd, omdat de leasecontainer de status behoudt, voegt de opstartcyclus van deze omgevingen vertragingen toe aan de tijd om meldingen te ontvangen. Dit komt door de overhead van het starten van de processor telkens wanneer de omgeving wordt gestart.
Toegangsvereisten op basis van rollen
Wanneer u Microsoft Entra ID als verificatiemechanisme gebruikt, moet u ervoor zorgen dat de identiteit over de juiste machtigingen beschikt:
- Op de bewaakte container:
Microsoft.DocumentDB/databaseAccounts/readMetadataMicrosoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeed
- In de leasecontainer:
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/readMicrosoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/createMicrosoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/replaceMicrosoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/deleteMicrosoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/executeQuery
Meer middelen
- Azure Cosmos DB SDK
- Volledige voorbeeldtoepassing op GitHub
- Gebruiksvoorbeelden op GitHub
- Workshoplabs van Azure Cosmos DB voor wijzigingenfeedprocessor
Volgende stappen
Meer informatie over de verwerker van wijzigingenfeeds vindt u in de volgende artikelen: