Berichten overdragen, vergrendelen en verwerken

De centrale mogelijkheid van een berichtenbroker, zoals Service Bus, is om berichten in een wachtrij of onderwerp te accepteren en deze beschikbaar te houden voor later ophalen. Verzenden is de term die vaak wordt gebruikt voor de overdracht van een bericht naar de berichtenbroker. Ontvangen is de term die vaak wordt gebruikt voor de overdracht van een bericht naar een ophalende client.

Wanneer een client een bericht verzendt, wil deze meestal weten of het bericht correct wordt overgebracht naar en geaccepteerd door de broker of dat er een fout is opgetreden. Met deze positieve of negatieve bevestiging wordt het begrip van zowel de client als de broker over de overdrachtsstatus van het bericht geregeld. Daarom wordt het een regeling genoemd.

Ook wanneer de broker een bericht overdraagt aan een client, willen de broker en de client bepalen of het bericht is verwerkt en daarom kan worden verwijderd, of of de bezorging of verwerking van het bericht is mislukt, en dus moet het bericht mogelijk opnieuw worden bezorgd.

Vereffeningsbewerkingen

Het gebruik van een van de ondersteunde Service Bus-API-clients, verzenden van bewerkingen naar Service Bus wordt altijd expliciet geregeld, wat betekent dat de API-bewerking wacht tot een acceptatieresultaat van Service Bus binnenkomt en vervolgens de verzendbewerking voltooit.

Als het bericht wordt geweigerd door Service Bus, bevat de afwijzing een foutindicator en tekst met daarin een tracerings-id . De afwijzing bevat ook informatie over of de bewerking opnieuw kan worden geprobeerd met een verwachting van succes. In de client wordt deze informatie omgezet in een uitzondering en naar de beller van de verzendbewerking verzonden. Als het bericht wordt geaccepteerd, wordt de bewerking op de achtergrond voltooid.

Advanced Messaging Queuing Protocol (AMQP) is het enige protocol dat wordt ondersteund voor .NET Standard-, Java-, JavaScript-, Python- en Go-clients. Voor .NET Framework-clients kunt u Service Bus Messaging Protocol (SBMP) of AMQP gebruiken. Wanneer u het AMQP-protocol gebruikt, worden berichtoverdrachten en stortingen gepijplijnd en asynchroon. U wordt aangeraden de API-varianten van het asynchrone programmeermodel te gebruiken.

Op 30 september 2026 gaan we de Azure Service Bus SDK-bibliotheken WindowsAzure.ServiceBus, Microsoft.Azure.ServiceBus en com.microsoft.azure.servicebus buiten gebruik stellen, die niet voldoen aan de Azure SDK-richtlijnen. We beëindigen ook de ondersteuning van het SBMP-protocol, zodat u dit protocol na 30 september 2026 niet meer kunt gebruiken. Migreer naar de nieuwste Azure SDK-bibliotheken, die vóór die datum essentiële beveiligingsupdates en verbeterde mogelijkheden bieden.

Hoewel de oudere bibliotheken nog steeds meer dan 30 september 2026 kunnen worden gebruikt, ontvangen ze geen officiële ondersteuning en updates meer van Microsoft. Zie de aankondiging van de buitengebruikstelling van de ondersteuning voor meer informatie.

Een afzender kan verschillende berichten op de draad snel achter elkaar plaatsen zonder te hoeven wachten tot elk bericht wordt bevestigd, zoals anders het geval is met het SBMP-protocol of met HTTP 1.1. Deze asynchrone verzendbewerkingen worden voltooid wanneer de respectieve berichten worden geaccepteerd en opgeslagen, op gepartitioneerde entiteiten of wanneer de verzendbewerking naar verschillende entiteiten overlappen. De voltooiingen kunnen ook voorkomen uit de oorspronkelijke verzendorder.

De strategie voor het afhandelen van het resultaat van verzendbewerkingen kan directe en aanzienlijke invloed hebben op de prestaties van uw toepassing. De voorbeelden in deze sectie zijn geschreven in C# en zijn van toepassing op Java-futures, Java-mono's, JavaScript-beloften en equivalente concepten in andere talen.

Als de toepassing bursts van berichten produceert, hier geïllustreerd met een gewone lus en wachten op de voltooiing van elke verzendbewerking voordat het volgende bericht, synchrone of asynchrone API-shapes worden verzonden, worden 10 berichten alleen na 10 opeenvolgende volledige retouren verzonden voor de afwikkeling.

Met een veronderstelde 70 milliseconden Transmission Control Protocol (TCP) retourlatentieafstand van een on-premises site naar Service Bus en slechts 10 ms voor Service Bus om elk bericht te accepteren en op te slaan, duurt de volgende lus ten minste 8 seconden, waarbij de nettoladingsoverdrachtstijd of mogelijke verkeersopstoppingseffecten niet worden geteld:

for (int i = 0; i < 10; i++)
{
    // creating the message omitted for brevity
    await sender.SendMessageAsync(message);
}

Als de toepassing de 10 asynchrone verzendbewerkingen direct achter elkaar start en de respectieve voltooiing ervan afzonderlijk wacht, overlapt de retourtijd voor die 10 verzendbewerkingen. De 10 berichten worden direct achter elkaar overgedragen, mogelijk zelfs TCP-frames delen en de totale overdrachtsduur is grotendeels afhankelijk van de netwerkgerelateerde tijd die nodig is om de berichten over te brengen naar de broker.

Met dezelfde veronderstellingen als voor de vorige lus kan de totale overlappende uitvoeringstijd voor de volgende lus een seconde lang blijven:

var tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
    tasks.Add(sender.SendMessageAsync(message));
}
await Task.WhenAll(tasks);

Het is belangrijk te weten dat alle asynchrone programmeermodellen een vorm van op geheugen gebaseerde, verborgen werkwachtrij gebruiken die in behandeling zijnde bewerkingen bevat. Wanneer de verzend-API wordt geretourneerd, wordt de verzendtaak in de wachtrij geplaatst in die werkwachtrij, maar wordt de protocolbeweging pas gestart zodra het de beurt is om de taak uit te voeren. Voor code die vaak bursts van berichten pusht en waar betrouwbaarheid een probleem is, moet u ervoor zorgen dat er niet te veel berichten 'in vlucht' tegelijk worden geplaatst, omdat alle verzonden berichten geheugen in beslag nemen totdat ze op de draad worden geplaatst.

Semaphores, zoals wordt weergegeven in het volgende codefragment in C#, zijn synchronisatieobjecten die dergelijke beperking op toepassingsniveau inschakelen wanneer dat nodig is. Met dit gebruik van een semafore kunnen maximaal 10 berichten tegelijk in vlucht zijn. Een van de 10 beschikbare semaphore-vergrendelingen wordt genomen voordat het verzenden wordt verzonden en wordt vrijgegeven als de verzend voltooid. De 11e pass door de lus wacht totdat ten minste één van de eerdere verzendbewerkingen is voltooid en maakt vervolgens de vergrendeling beschikbaar:

var semaphore = new SemaphoreSlim(10);

var tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
    await semaphore.WaitAsync();

    tasks.Add(sender.SendMessageAsync(message).ContinueWith((t)=>semaphore.Release()));
}
await Task.WhenAll(tasks);

Toepassingen mogen nooit een asynchrone verzendbewerking starten op een 'fire and forget'-manier zonder het resultaat van de bewerking op te halen. Hierdoor kan de interne en onzichtbare taakwachtrij worden geladen tot geheugenuitputting en wordt voorkomen dat de toepassing verzendfouten detecteert:

for (int i = 0; i < 10; i++)
{
    sender.SendMessageAsync(message); // DON’T DO THIS
}

Met een AMQP-client op laag niveau accepteert Service Bus ook 'vooraf ingestelde' overdrachten. Een vooraf ingestelde overdracht is een fire-and-forget-bewerking waarvoor het resultaat, in beide gevallen, niet aan de client wordt gerapporteerd en het bericht wordt beschouwd als vereffend wanneer het wordt verzonden. Het gebrek aan feedback aan de client betekent ook dat er geen bruikbare gegevens beschikbaar zijn voor diagnostische gegevens, wat betekent dat deze modus niet in aanmerking komt voor hulp via ondersteuning voor Azure.

Settling receive operations

Voor ontvangstbewerkingen schakelen de Service Bus API-clients twee verschillende expliciete modi in: Receive-and-Delete en Peek-Lock.

ReceiveAndDelete

De modus Ontvangen en verwijderen vertelt de broker om alle berichten te overwegen die naar de ontvangende client worden verzonden, zoals die zijn geregeld wanneer ze worden verzonden. Dat betekent dat het bericht wordt beschouwd als verbruikt zodra de broker het op de draad plaatst. Als de berichtoverdracht mislukt, gaat het bericht verloren.

Het voordeel van deze modus is dat de ontvanger geen verdere actie hoeft te ondernemen op het bericht en ook niet wordt vertraagd door te wachten op het resultaat van de afwikkeling. Als de gegevens in de afzonderlijke berichten een lage waarde hebben en/of alleen zinvol zijn voor een zeer korte tijd, is deze modus een redelijke keuze.

PeekLock

De peek-lock-modus vertelt de broker dat de ontvangende client expliciet ontvangen berichten wil vereffenen. Het bericht wordt beschikbaar gesteld zodat de ontvanger het kan verwerken, terwijl het onder een exclusieve vergrendeling in de service wordt gehouden, zodat andere concurrerende ontvangers het niet kunnen zien. De duur van de vergrendeling wordt in eerste instantie gedefinieerd op het niveau van de wachtrij of het abonnement en kan worden verlengd door de client die eigenaar is van de vergrendeling, via de bewerking RenewMessageLockAsync . Zie de sectie Vergrendelingen vernieuwen in dit artikel voor meer informatie over het vernieuwen van vergrendelingen .

Wanneer een bericht is vergrendeld, kunnen andere clients die van dezelfde wachtrij of hetzelfde abonnement ontvangen, vergrendelingen in beslag nemen en de volgende beschikbare berichten ophalen die niet onder actieve vergrendeling staan. Wanneer de vergrendeling op een bericht expliciet wordt vrijgegeven of wanneer de vergrendeling verloopt, wordt het bericht vóór de ophaalvolgorde geplaatst voor opnieuw afspelen.

Wanneer het bericht herhaaldelijk wordt vrijgegeven door ontvangers of wanneer de vergrendeling gedurende een bepaald aantal keren is verstreken (max. aantal bezorgingen), wordt het bericht automatisch verwijderd uit de wachtrij of het abonnement en in de bijbehorende wachtrij met dode brieven geplaatst.

De ontvangende client initieert de afwikkeling van een ontvangen bericht met een positieve bevestiging wanneer deze de Complete API voor het bericht aanroept. Dit geeft aan de broker aan dat het bericht is verwerkt en dat het bericht wordt verwijderd uit de wachtrij of het abonnement. De broker reageert op de afwikkelingsintentie van de ontvanger met een antwoord dat aangeeft of de afwikkeling kan worden uitgevoerd.

Wanneer de ontvangende client een bericht niet kan verwerken, maar het bericht opnieuw moet worden verzonden, kan het expliciet vragen of het bericht onmiddellijk wordt vrijgegeven en ontgrendeld door de Api voor verlaten aan te roepen voor het bericht of het kan niets doen en de vergrendeling laten verlopen.

Als een ontvangende client een bericht niet kan verwerken en weet dat het bericht opnieuw verzenden en het opnieuw proberen van de bewerking niet kan helpen, kan het bericht worden geweigerd, waardoor het wordt verplaatst naar de wachtrij voor dode letters door de DeadLetter-API aan te roepen voor het bericht, waardoor ook een aangepaste eigenschap kan worden ingesteld, inclusief een redencode die kan worden opgehaald met het bericht uit de wachtrij voor dode letters.

Notitie

Er bestaat alleen een wachtrij of een onderwerpabonnement als u de functie voor dode letters hebt ingeschakeld voor de wachtrij of het abonnement.

Een speciaal geval van afwikkeling is uitstel, dat in een apart artikel wordt besproken.

De Completebewerkingen of RenewLockDeadLetterbewerkingen kunnen mislukken vanwege netwerkproblemen, als de vastgehouden vergrendeling is verlopen of er andere voorwaarden aan de servicezijde zijn die de afwikkeling verhinderen. In een van de laatste gevallen verzendt de service een negatieve bevestiging die optreedt als een uitzondering in de API-clients. Als de reden een verbroken netwerkverbinding is, wordt de vergrendeling verbroken omdat Service Bus geen ondersteuning biedt voor herstel van bestaande AMQP-koppelingen op een andere verbinding.

Als Complete dit mislukt, wat meestal aan het einde van de verwerking van berichten plaatsvindt en in sommige gevallen na enkele minuten van het verwerken van werk, kan de ontvangende toepassing beslissen of de status van het werk behouden moet blijven en hetzelfde bericht moet worden genegeerd wanneer het een tweede keer wordt bezorgd of of het werkresultaat wordt weggeteld en opnieuw wordt geprobeerd wanneer het bericht opnieuw wordt verzonden.

Het gebruikelijke mechanisme voor het identificeren van dubbele berichtleveringen is door de bericht-id te controleren, die door de afzender kan worden ingesteld op een unieke waarde, mogelijk afgestemd op een id van het oorspronkelijke proces. Een jobplanner zou waarschijnlijk de bericht-id instellen op de id van de taak die deze probeert toe te wijzen aan een werkrol met de opgegeven werkrol. De werkrol negeert het tweede exemplaar van de taaktoewijzing als die taak al is voltooid.

Belangrijk

Het is belangrijk om te weten dat de vergrendeling die PeekLock of SessionLock op het bericht verkrijgt, vluchtig is en in de volgende omstandigheden verloren kan gaan

  • Service-update
  • Update van besturingssysteem
  • Eigenschappen voor de entiteit wijzigen (wachtrij, onderwerp, abonnement) terwijl de vergrendeling wordt vastgehouden.

Wanneer de vergrendeling is verbroken, genereert Azure Service Bus een MessageLockLostException of SessionLockLostException, die wordt weergegeven in de clienttoepassing. In dit geval moet de standaardlogica voor opnieuw proberen van de client automatisch worden geactiveerd en moet de bewerking opnieuw worden geprobeerd.

Vergrendelingen vernieuwen

De standaardwaarde voor de vergrendelingsduur is 1 minuut. U kunt een andere waarde opgeven voor de duur van de vergrendeling op wachtrij- of abonnementsniveau. De client die eigenaar is van de vergrendeling, kan de berichtvergrendeling vernieuwen met behulp van methoden op het ontvangerobject. In plaats daarvan kunt u de functie voor automatische vergrendelingsvernieuwing gebruiken, waarin u de tijdsduur kunt opgeven waarvoor u de vergrendeling wilt verlengen.

Het is raadzaam om de duur van de vergrendeling in te stellen op iets hoger dan de normale verwerkingstijd, zodat u de vergrendeling niet hoeft te vernieuwen. De maximumwaarde is 5 minuten, dus u moet de vergrendeling verlengen als u deze langer wilt hebben. Het hebben van een langere vergrendelingsduur dan nodig heeft ook enkele gevolgen. Als uw client bijvoorbeeld niet meer werkt, wordt het bericht alleen weer beschikbaar nadat de vergrendelingsduur is verstreken.

Volgende stappen