Reliable Services-meldingen
Met meldingen kunnen clients de wijzigingen bijhouden die worden aangebracht in een object waarin ze geïnteresseerd zijn. Twee typen objecten ondersteunen meldingen: Reliable State Manager en Reliable Dictionary.
Veelvoorkomende redenen voor het gebruik van meldingen zijn:
- Gerealiseerde weergaven bouwen, zoals secundaire indexen of geaggregeerde gefilterde weergaven van de status van de replica. Een voorbeeld is een gesorteerde index van alle sleutels in Reliable Dictionary.
- Bewakingsgegevens verzenden, zoals het aantal gebruikers dat in het afgelopen uur is toegevoegd.
Meldingen worden geactiveerd als onderdeel van het toepassen van bewerkingen. Op een primaire replica worden bewerkingen toegepast na quorumbevestiging als onderdeel van transaction.CommitAsync()
of this.StateManager.GetOrAddAsync()
. Op secundaire replica's worden bewerkingen toegepast bij de verwerking van replicatiewachtrijgegevens. Daarom moeten meldingen zo snel mogelijk worden verwerkt en moeten synchrone gebeurtenissen geen dure bewerkingen bevatten. Anders kan dit een negatieve invloed hebben op de verwerkingstijd van transacties en op replica-build-ups.
Reliable State Manager-meldingen
Reliable State Manager biedt meldingen voor de volgende gebeurtenissen:
- Transactie
- Doorvoeren
- Statusmanager
- Opnieuw bouwen
- Toevoeging van een betrouwbare status
- Verwijderen van een betrouwbare status
Reliable State Manager houdt de huidige actieve transacties bij. De enige wijziging in de transactiestatus waardoor een melding wordt geactiveerd, is een transactie die wordt doorgevoerd.
Reliable State Manager onderhoudt een verzameling betrouwbare statussen zoals Reliable Dictionary en Reliable Queue. Reliable State Manager krijgt meldingen wanneer deze verzameling wordt gewijzigd: een betrouwbare status wordt toegevoegd of verwijderd, of de hele verzameling wordt opnieuw opgebouwd. De verzameling Reliable State Manager wordt in drie gevallen opnieuw opgebouwd:
- Herstel: Wanneer een replica wordt gestart, wordt de vorige status van de schijf hersteld. Aan het einde van het herstel wordt gebruikgemaakt van NotifyStateManagerChangedEventArgs om een gebeurtenis te activeren die de set herstelde betrouwbare statussen bevat.
- Volledige kopie: Voordat een replica lid kan worden van de configuratieset, moet deze worden gebouwd. Soms moet hiervoor een volledige kopie van de status van Reliable State Manager van de primaire replica worden toegepast op de niet-actieve secundaire replica. Reliable State Manager op de secundaire replica maakt gebruik van NotifyStateManagerChangedEventArgs om een gebeurtenis te activeren die de set betrouwbare statussen bevat die zijn verkregen van de primaire replica.
- Herstellen: In scenario's voor herstel na noodgevallen kan de status van de replica worden hersteld vanuit een back-up via RestoreAsync. In dergelijke gevallen gebruikt Reliable State Manager op de primaire replica NotifyStateManagerChangedEventArgs om een gebeurtenis te activeren die de set betrouwbare statussen bevat die vanuit de back-up zijn hersteld.
Als u zich wilt registreren voor transactiemeldingen en/of statusmanagermeldingen, moet u zich registreren bij de gebeurtenissen TransactionChanged of StateManagerChanged op Reliable State Manager. Een algemene plaats om u te registreren bij deze gebeurtenis-handlers is de constructor van uw stateful service. Wanneer u zich registreert bij de constructor, mist u geen melding die wordt veroorzaakt door een wijziging tijdens de levensduur van IReliableStateManager.
public MyService(StatefulServiceContext context)
: base(MyService.EndpointName, context, CreateReliableStateManager(context))
{
this.StateManager.TransactionChanged += this.OnTransactionChangedHandler;
this.StateManager.StateManagerChanged += this.OnStateManagerChangedHandler;
}
De TransactionChanged-gebeurtenishandler maakt gebruik van NotifyTransactionChangedEventArgs om details over de gebeurtenis op te geven. Het bevat de actie-eigenschap (bijvoorbeeld NotifyTransactionChangedAction.Commit) die het type wijziging aangeeft. Het bevat ook de transactie-eigenschap die een verwijzing biedt naar de transactie die is gewijzigd.
Notitie
Momenteel worden TransactionChanged-gebeurtenissen alleen gegenereerd als de transactie wordt doorgevoerd. De actie is vervolgens gelijk aan NotifyTransactionChangedAction.Commit. Maar in de toekomst kunnen gebeurtenissen worden gegenereerd voor andere typen wijzigingen in de transactiestatus. We raden u aan de actie te controleren en de gebeurtenis alleen te verwerken als deze een gebeurtenis is die u verwacht.
Hieronder volgt een voorbeeld van transactionChanged-gebeurtenis-handler .
private void OnTransactionChangedHandler(object sender, NotifyTransactionChangedEventArgs e)
{
if (e.Action == NotifyTransactionChangedAction.Commit)
{
this.lastCommitLsn = e.Transaction.CommitSequenceNumber;
this.lastTransactionId = e.Transaction.TransactionId;
this.lastCommittedTransactionList.Add(e.Transaction.TransactionId);
}
}
De StateManagerChanged-gebeurtenishandler maakt gebruik van NotifyStateManagerChangedEventArgs om details over de gebeurtenis op te geven. NotifyStateManagerChangedEventArgs heeft twee subklassen: NotifyStateManagerRebuildEventArgs en NotifyStateManagerSingleEntityChangedEventArgs. U gebruikt de actie-eigenschap in NotifyStateManagerChangedEventArgs om NotifyStateManagerChangedEventArgs te casten naar de juiste subklasse:
- NotifyStateManagerChangedAction.Rebuild: NotifyStateManagerRebuildEventArgs
- NotifyStateManagerChangedAction.Add en NotifyStateManagerChangedAction.Remove: NotifyStateManagerSingleEntityChangedEventArgs
Hieronder volgt een voorbeeld van een StateManagerChanged-meldingshandler .
public void OnStateManagerChangedHandler(object sender, NotifyStateManagerChangedEventArgs e)
{
if (e.Action == NotifyStateManagerChangedAction.Rebuild)
{
this.ProcessStateManagerRebuildNotification(e);
return;
}
this.ProcessStateManagerSingleEntityNotification(e);
}
Betrouwbare woordenlijstmeldingen
Reliable Dictionary biedt meldingen voor de volgende gebeurtenissen:
- Herbouw: aangeroepen wanneer ReliableDictionary is hersteld naar een leesbare herstelstatus van een herstelde of gekopieerde lokale status of back-up. Een record van transacties sinds het maken van deze herstelstatus wordt vervolgens toegepast voordat de herbouw is voltooid. De toepassing van deze record biedt duidelijke meldingen, toevoegen, bijwerken en/of verwijderen.
- Clear: Aangeroepen wanneer de status ReliableDictionary is gewist via de ClearAsync-methode.
- Toevoegen: Aangeroepen wanneer een item is toegevoegd aan ReliableDictionary.
- Update: Aangeroepen wanneer een item in IReliableDictionary is bijgewerkt.
- Verwijderen: Aangeroepen wanneer een item in IReliableDictionary is verwijderd.
Als u reliable dictionary-meldingen wilt ontvangen, moet u zich registreren bij de gebeurtenis-handler DictionaryChanged op IReliableDictionary. Een veelvoorkomende plaats voor registratie bij deze gebeurtenis-handlers vindt u in de melding ReliableStateManager.StateManagerChanged add. Registreren wanneer IReliableDictionary wordt toegevoegd aan IReliableStateManager zorgt ervoor dat u geen meldingen mist.
private void ProcessStateManagerSingleEntityNotification(NotifyStateManagerChangedEventArgs e)
{
var operation = e as NotifyStateManagerSingleEntityChangedEventArgs;
if (operation.Action == NotifyStateManagerChangedAction.Add)
{
if (operation.ReliableState is IReliableDictionary<TKey, TValue>)
{
var dictionary = (IReliableDictionary<TKey, TValue>)operation.ReliableState;
dictionary.RebuildNotificationAsyncCallback = this.OnDictionaryRebuildNotificationHandlerAsync;
dictionary.DictionaryChanged += this.OnDictionaryChangedHandler;
}
}
}
Notitie
ProcessStateManagerSingleEntityNotification is de voorbeeldmethode die in het voorgaande OnStateManagerChangedHandler-voorbeeld wordt aangeroepen.
Met de voorgaande code wordt de interface IReliableNotificationAsyncCallback ingesteld, samen met DictionaryChanged. Omdat NotifyDictionaryRebuildEventArgs een IAsyncEnumerable interface bevat, die moet worden geïnventariseerd asynchroon-herbouwmeldingen worden geactiveerd via RebuildNotificationAsyncCallback in plaats van OnDictionaryChangedHandler.
public async Task OnDictionaryRebuildNotificationHandlerAsync(
IReliableDictionary<TKey, TValue> origin,
NotifyDictionaryRebuildEventArgs<TKey, TValue> rebuildNotification)
{
this.secondaryIndex.Clear();
var enumerator = e.State.GetAsyncEnumerator();
while (await enumerator.MoveNextAsync(CancellationToken.None))
{
this.secondaryIndex.Add(enumerator.Current.Key, enumerator.Current.Value);
}
}
Notitie
In de voorgaande code, als onderdeel van het verwerken van de herbouwmelding, wordt eerst de samengevoegde status gewist. Omdat de betrouwbare verzameling opnieuw wordt opgebouwd met een nieuwe status, zijn alle eerdere meldingen irrelevant.
De Gebeurtenis-handler DictionaryChanged maakt gebruik van NotifyDictionaryChangedEventArgs om details over de gebeurtenis op te geven. NotifyDictionaryChangedEventArgs heeft vijf subklassen. Gebruik de actie-eigenschap in NotifyDictionaryChangedEventArgs om NotifyDictionaryChangedEventArgs te casten naar de juiste subklasse:
- NotifyDictionaryChangedAction.Rebuild: NotifyDictionaryRebuildEventArgs
- NotifyDictionaryChangedAction.Clear: NotifyDictionary DictateEventArgs
- NotifyDictionaryChangedAction.Add: NotifyDictionaryItemAddedEventArgs
- NotifyDictionaryChangedAction.Update: NotifyDictionaryItemUpdatedEventArgs
- NotifyDictionaryChangedAction.Remove: NotifyDictionaryItemRemovedEventArgs
public void OnDictionaryChangedHandler(object sender, NotifyDictionaryChangedEventArgs<TKey, TValue> e)
{
switch (e.Action)
{
case NotifyDictionaryChangedAction.Clear:
var clearEvent = e as NotifyDictionaryClearEventArgs<TKey, TValue>;
this.ProcessClearNotification(clearEvent);
return;
case NotifyDictionaryChangedAction.Add:
var addEvent = e as NotifyDictionaryItemAddedEventArgs<TKey, TValue>;
this.ProcessAddNotification(addEvent);
return;
case NotifyDictionaryChangedAction.Update:
var updateEvent = e as NotifyDictionaryItemUpdatedEventArgs<TKey, TValue>;
this.ProcessUpdateNotification(updateEvent);
return;
case NotifyDictionaryChangedAction.Remove:
var deleteEvent = e as NotifyDictionaryItemRemovedEventArgs<TKey, TValue>;
this.ProcessRemoveNotification(deleteEvent);
return;
default:
break;
}
}
Aanbevelingen
- Voltooi meldingen zo snel mogelijk.
- Voer geen dure bewerkingen (bijvoorbeeld I/O-bewerkingen) uit als onderdeel van synchrone gebeurtenissen.
- Controleer het actietype voordat u de gebeurtenis verwerkt. Nieuwe actietypen kunnen in de toekomst worden toegevoegd.
Hier zijn een aantal zaken waar u rekening mee moet houden:
- Meldingen worden geactiveerd als onderdeel van de uitvoering van een bewerking. Een herstelmelding wordt bijvoorbeeld geactiveerd als een stap van een herstelbewerking. Een herstelbewerking wordt pas voortgezet nadat de meldingsgebeurtenis is verwerkt.
- Omdat meldingen worden geactiveerd als onderdeel van de toepassingsbewerkingen, zien clients alleen meldingen voor lokaal doorgevoerde bewerkingen. En omdat bewerkingen gegarandeerd alleen lokaal worden doorgevoerd (met andere woorden, vastgelegd), kunnen ze in de toekomst wel of niet ongedaan worden gemaakt.
- Op het redo-pad wordt één melding geactiveerd voor elke toegepaste bewerking. Dit betekent dat als transactie T1 Create(X), Delete(X) en Create(X) bevat, u één melding krijgt voor het maken van X, één voor de verwijdering en een voor het opnieuw maken, in die volgorde.
- Voor transacties die meerdere bewerkingen bevatten, worden bewerkingen toegepast in de volgorde waarin ze zijn ontvangen op de primaire replica van de gebruiker.
- Als onderdeel van het verwerken van de foutieve voortgang, kunnen sommige bewerkingen ongedaan worden gemaakt op secundaire replica's. Meldingen worden gegenereerd voor dergelijke ongedaan maken bewerkingen, die de status van de replica terugdraaien naar een stabiel punt. Een belangrijk verschil in het ongedaan maken van meldingen is dat gebeurtenissen met dubbele sleutels worden samengevoegd. Als transactie T1 bijvoorbeeld ongedaan wordt gemaakt, ziet u één melding voor Delete(X).
Volgende stappen
- Betrouwbare verzamelingen
- Quickstart voor Reliable Services
- Reliable Services-back-up en herstel (herstel na noodgevallen)
- Naslaginformatie voor ontwikkelaars voor Betrouwbare verzamelingen
Bekende problemen
- In specifieke situaties kunnen sommige transactiemeldingen worden overgeslagen tijdens een herbouwing. In dit geval is de juiste waarde nog steeds aanwezig en kan deze nog steeds worden gelezen of curseerd; alleen de melding ontbreekt. Voor het herstellen van de status in het geheugen maken betrouwbare verzamelingen gebruik van een write-ahead-logboek dat periodiek wordt omgezet in een controlepuntbestand. Tijdens het herstellen wordt eerst de basisstatus geladen vanuit controlepuntbestanden die een herbouwmelding activeren. Vervolgens worden de transacties die zijn opgeslagen in het logboek toegepast. Elke trigger die het activeert, is een melding voor wissen, toevoegen, bijwerken of verwijderen. Dit probleem kan zich voordoen bij een racevoorwaarde waarbij een nieuw controlepunt snel wordt genomen na een herstelbewerking. Als het controlepunt is voltooid vóór de toepassing van het logboek, wordt de geheugenstatus ingesteld op de status van het nieuwe controlepunt. Hoewel dit de juiste status oplevert, betekent dit dat transacties in het logboek die nog niet zijn toegepast, geen meldingen verzenden.