Aan de slag met Reliable Services
Een Azure Service Fabric-toepassing bevat een of meer services die uw code uitvoeren. Deze handleiding laat zien hoe u stateless en stateful Service Fabric-toepassingen maakt met Reliable Services.
Basisbegrippen
Als u aan de slag wilt gaan met Reliable Services, hoeft u slechts enkele basisconcepten te begrijpen:
- Servicetype: dit is uw service-implementatie. Deze wordt gedefinieerd door de klasse die u schrijft en
StatelessService
alle andere code of afhankelijkheden die daarin worden gebruikt, samen met een naam en een versienummer. - Benoemd service-exemplaar: Als u uw service wilt uitvoeren, maakt u benoemde exemplaren van uw servicetype, net zoals u objectexemplaren van een klassetype maakt. Een service-exemplaar heeft een naam in de vorm van een URI met behulp van het schema 'fabric:/' zoals 'fabric:/MyApp/MyService'.
- Servicehost: de benoemde service-exemplaren die u maakt, moeten worden uitgevoerd in een hostproces. De servicehost is slechts een proces waarbij exemplaren van uw service kunnen worden uitgevoerd.
- Serviceregistratie: Registratie brengt alles samen. Het servicetype moet worden geregistreerd bij de Service Fabric-runtime in een servicehost, zodat Service Fabric exemplaren kan maken die kunnen worden uitgevoerd.
Een stateless service maken
Een stateless service is een type service dat momenteel de norm is in cloudtoepassingen. Het wordt beschouwd als staatloos omdat de service zelf geen gegevens bevat die betrouwbaar moeten worden opgeslagen of maximaal beschikbaar moeten worden gemaakt. Als een exemplaar van een staatloze service wordt afgesloten, gaat alle interne status verloren. In dit type service moet de status worden behouden in een extern archief, zoals Azure Tables of SQL Database, om deze maximaal beschikbaar en betrouwbaar te maken.
Start Visual Studio 2017 of Visual Studio 2019 als beheerder en maak een nieuw Service Fabric-toepassingsproject met de naam HelloWorld:
Maak vervolgens een stateless serviceproject met behulp van .NET Core 2.0 met de naam HelloWorldStateless:
Uw oplossing bevat nu twee projecten:
- HelloWorld. Dit is het toepassingsproject dat uw services bevat. Het bevat ook het toepassingsmanifest dat de toepassing beschrijft, evenals een aantal PowerShell-scripts waarmee u uw toepassing kunt implementeren.
- HelloWorldStateless. Dit is het serviceproject. Het bevat de stateless service-implementatie.
De service implementeren
Open het bestand HelloWorldStateless.cs in het serviceproject. In Service Fabric kan een service elke bedrijfslogica uitvoeren. De service-API biedt twee toegangspunten voor uw code:
- Een open-ended ingangspuntmethode, RunAsync, waar u kunt beginnen met het uitvoeren van workloads, inclusief langlopende rekenworkloads.
protected override async Task RunAsync(CancellationToken cancellationToken)
{
...
}
- Een communicatie-ingangspunt waar u uw communicatiestack van keuze kunt aansluiten, zoals ASP.NET Core. Hier kunt u aanvragen ontvangen van gebruikers en andere services.
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
...
}
In deze zelfstudie richten we ons op de RunAsync()
invoerpuntmethode. Hier kunt u direct beginnen met het uitvoeren van uw code.
De projectsjabloon bevat een voorbeeld-implementatie van RunAsync()
die een doorlopend aantal verhogen.
Notitie
Zie Servicecommunicatie met ASP.NET Core voor meer informatie over het werken met een communicatiestack
RunAsync
protected override async Task RunAsync(CancellationToken cancellationToken)
{
// TODO: Replace the following sample code with your own logic
// or remove this RunAsync override if it's not needed in your service.
long iterations = 0;
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
ServiceEventSource.Current.ServiceMessage(this.Context, "Working-{0}", ++iterations);
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
}
}
Het platform roept deze methode aan wanneer een exemplaar van een service wordt geplaatst en klaar is om uit te voeren. Voor een staatloze service betekent dit simpelweg wanneer het service-exemplaar wordt geopend. Er wordt een annuleringstoken verstrekt om te coördineren wanneer uw service-exemplaar moet worden gesloten. In Service Fabric kan deze open/sluiten cyclus van een service-exemplaar zich vaak voordoen gedurende de levensduur van de service als geheel. Dit kan om verschillende redenen gebeuren, waaronder:
- Het systeem verplaatst uw service-exemplaren voor resourceverdeling.
- Er treden fouten op in uw code.
- De toepassing of het systeem wordt bijgewerkt.
- De onderliggende hardware ondervindt een storing.
Deze indeling wordt beheerd door het systeem om uw service maximaal beschikbaar en correct in balans te houden.
RunAsync()
mag niet synchroon worden geblokkeerd. Uw implementatie van RunAsync moet een taak retourneren of wachten op langlopende of blokkerende bewerkingen om de runtime door te laten gaan. Opmerking in de while(true)
lus in het vorige voorbeeld wordt een taak geretourneerd await Task.Delay()
. Als uw workload synchroon moet worden geblokkeerd, moet u een nieuwe taak plannen Task.Run()
in uw RunAsync
implementatie.
Annulering van uw workload is een gezamenlijke inspanning die wordt ingedeeld door het opgegeven annuleringstoken. Het systeem wacht totdat uw taak is beëindigd (door geslaagde voltooiing, annulering of fout) voordat de taak wordt uitgevoerd. Het is belangrijk om het annuleringstoken te respecteren, werk te voltooien en zo snel mogelijk af te sluiten RunAsync()
wanneer het systeem annulering aanvraagt.
In dit staatloze servicevoorbeeld wordt het aantal opgeslagen in een lokale variabele. Maar omdat dit een staatloze service is, bestaat de waarde die is opgeslagen alleen voor de huidige levenscyclus van het service-exemplaar. Wanneer de service wordt verplaatst of opnieuw wordt opgestart, gaat de waarde verloren.
Een stateful service maken
Service Fabric introduceert een nieuw type service dat stateful is. Een stateful service kan de status betrouwbaar binnen de service zelf onderhouden, samen met de code die deze gebruikt. De status wordt maximaal beschikbaar gesteld door Service Fabric zonder dat de status moet worden bewaard in een externe winkel.
Als u een tellerwaarde wilt converteren van staatloos naar maximaal beschikbaar en permanent, zelfs wanneer de service wordt verplaatst of opnieuw wordt opgestart, hebt u een stateful service nodig.
In dezelfde HelloWorld-toepassing kunt u een nieuwe service toevoegen door met de rechtermuisknop op de Services-verwijzingen in het toepassingsproject te klikken en Add -> New Service Fabric Service te selecteren.
Selecteer .NET Core 2.0 -> Stateful Service en noem deze HelloWorldStateful. Klik op OK.
Uw toepassing moet nu twee services hebben: de stateless service HelloWorldStateless en de stateful service HelloWorldStateful.
Een stateful service heeft dezelfde toegangspunten als een staatloze service. Het belangrijkste verschil is de beschikbaarheid van een statusprovider die de status betrouwbaar kan opslaan. Service Fabric wordt geleverd met een statusprovider-implementatie met de naam Reliable Collections, waarmee u gerepliceerde gegevensstructuren kunt maken via Reliable State Manager. Een stateful Reliable Service maakt standaard gebruik van deze statusprovider.
Open HelloWorldStateful.cs in HelloWorldStateful, die de volgende RunAsync-methode bevat:
protected override async Task RunAsync(CancellationToken cancellationToken)
{
// TODO: Replace the following sample code with your own logic
// or remove this RunAsync override if it's not needed in your service.
var myDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<string, long>>("myDictionary");
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
using (var tx = this.StateManager.CreateTransaction())
{
var result = await myDictionary.TryGetValueAsync(tx, "Counter");
ServiceEventSource.Current.ServiceMessage(this.Context, "Current Counter Value: {0}",
result.HasValue ? result.Value.ToString() : "Value does not exist.");
await myDictionary.AddOrUpdateAsync(tx, "Counter", 0, (key, value) => ++value);
// If an exception is thrown before calling CommitAsync, the transaction aborts, all changes are
// discarded, and nothing is saved to the secondary replicas.
await tx.CommitAsync();
}
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
}
RunAsync
RunAsync()
werkt op dezelfde manier in stateful en stateless services. In een stateful service voert het platform echter namens u extra werk uit voordat het wordt uitgevoerd RunAsync()
. Dit werk kan omvatten om ervoor te zorgen dat Reliable State Manager en Reliable Collections gereed zijn voor gebruik.
Betrouwbare verzamelingen en de Reliable State Manager
var myDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<string, long>>("myDictionary");
IReliableDictionary is een woordenlijstimplementatie die u kunt gebruiken om de status betrouwbaar op te slaan in de service. Met Service Fabric en Reliable Collections kunt u gegevens rechtstreeks in uw service opslaan zonder dat u een extern permanent archief nodig hebt. Betrouwbare verzamelingen maken uw gegevens maximaal beschikbaar. Service Fabric doet dit door meerdere replica's van uw service voor u te maken en te beheren. Het biedt ook een API waarmee de complexiteit van het beheren van deze replica's en hun statusovergangen wordt weggenomen.
Betrouwbare verzamelingen kunnen elk .NET-type opslaan, inclusief uw aangepaste typen, met een aantal opmerkingen:
Service Fabric maakt uw status maximaal beschikbaar door de status over knooppunten te repliceren en Betrouwbare verzamelingen slaan uw gegevens op de lokale schijf op elke replica op. Dit betekent dat alles wat is opgeslagen in Reliable Collections serialiseerbaar moet zijn. Betrouwbare verzamelingen maken standaard gebruik van DataContract voor serialisatie, dus het is belangrijk om ervoor te zorgen dat uw typen worden ondersteund door de Data Contract Serializer wanneer u de standaard serializer gebruikt.
Objecten worden gerepliceerd voor hoge beschikbaarheid wanneer u transacties doorvoert op Betrouwbare verzamelingen. Objecten die zijn opgeslagen in Betrouwbare verzamelingen, worden in het lokale geheugen in uw service bewaard. Dit betekent dat u een lokale verwijzing naar het object hebt.
Het is belangrijk dat u lokale exemplaren van deze objecten niet muteert zonder een updatebewerking uit te voeren op de betrouwbare verzameling in een transactie. Dit komt doordat wijzigingen in lokale exemplaren van objecten niet automatisch worden gerepliceerd. U moet het object opnieuw invoegen in de woordenlijst of een van de updatemethoden in de woordenlijst gebruiken.
Reliable State Manager beheert Betrouwbare verzamelingen voor u. U kunt de Reliable State Manager gewoon op elk gewenst moment en op elke plaats in uw service vragen om een betrouwbare verzameling op naam. De Reliable State Manager zorgt ervoor dat u een referentie terug krijgt. We raden u niet aan verwijzingen op te slaan naar betrouwbare verzamelingsexemplaren in klasselidvariabelen of -eigenschappen. Zorg ervoor dat de verwijzing altijd is ingesteld op een exemplaar in de levenscyclus van de service. De Reliable State Manager verwerkt dit werk voor u en is geoptimaliseerd voor herhaalbezoeken.
Transactionele en asynchrone bewerkingen
using (ITransaction tx = this.StateManager.CreateTransaction())
{
var result = await myDictionary.TryGetValueAsync(tx, "Counter-1");
await myDictionary.AddOrUpdateAsync(tx, "Counter-1", 0, (k, v) => ++v);
await tx.CommitAsync();
}
Betrouwbare verzamelingen hebben veel van dezelfde bewerkingen als hun System.Collections.Generic
System.Collections.Concurrent
tegenhangers, met uitzondering van Language Integrated Query (LINQ). Bewerkingen op betrouwbare verzamelingen zijn asynchroon. Dit komt doordat schrijfbewerkingen met Reliable Collections I/O-bewerkingen uitvoeren om gegevens naar schijf te repliceren en te behouden.
Betrouwbare verzamelingsbewerkingen zijn transactioneel, zodat u de status consistent kunt houden in meerdere Betrouwbare verzamelingen en bewerkingen. U kunt bijvoorbeeld een werkitem uit een betrouwbare wachtrij verwijderen, er een bewerking op uitvoeren en het resultaat opslaan in een betrouwbare woordenlijst, allemaal binnen één transactie. Dit wordt behandeld als een atomische bewerking en garandeert dat de hele bewerking slaagt of dat de hele bewerking wordt teruggedraaid. Als er een fout optreedt nadat u het item uit de wachtrij hebt verwijderd, maar voordat u het resultaat opslaat, wordt de hele transactie teruggedraaid en blijft het item in de wachtrij voor verwerking.
De toepassing uitvoeren
We gaan nu terug naar de Toepassing HelloWorld . U kunt nu uw services bouwen en implementeren. Wanneer u op F5 drukt, wordt uw toepassing gebouwd en geïmplementeerd in uw lokale cluster.
Nadat de services zijn uitgevoerd, kunt u de gegenereerde ETW-gebeurtenissen (Event Tracing for Windows) bekijken in een venster diagnostische gebeurtenissen . Houd er rekening mee dat de weergegeven gebeurtenissen afkomstig zijn van zowel de stateless service als de stateful service in de toepassing. U kunt de stream onderbreken door op de knop Onderbreken te klikken. Vervolgens kunt u de details van een bericht bekijken door dat bericht uit te vouwen.
Notitie
Voordat u de toepassing uitvoert, moet u ervoor zorgen dat er een lokaal ontwikkelcluster wordt uitgevoerd. Bekijk de introductiehandleiding voor informatie over het instellen van uw lokale omgeving.
Volgende stappen
Fouten opsporen in uw Service Fabric-toepassing in Visual Studio
Aan de slag: Service Fabric-web-API-services met zelfhosting voor OWIN