Aan de slag met Reliable Services

Een Azure Service Fabric-toepassing bevat een of meer services waarmee uw code wordt uitgevoerd. In deze handleiding wordt beschreven hoe u zowel stateless als stateful Service Fabric-toepassingen maakt met Reliable Services.

Bekijk deze pagina voor een trainingsvideo die u ook laat zien hoe u een staatloze betrouwbare service kunt maken.

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 eventuele andere code of afhankelijkheden die StatelessService hierin 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 de 'fabric:/' schema, 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 van het service-type kan maken om uit te voeren.

Een staatloze 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 de hele interne status verloren. In dit type service moet de status worden opgeslagen 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:

Het dialoogvenster Nieuw project gebruiken om een nieuwe Service Fabric-toepassing te maken

Maak vervolgens een staatloos serviceproject met behulp van .NET Core 2.0 met de naam HelloWorldStateless:

Maak in het tweede dialoogvenster een staatloos serviceproject

Uw oplossing bevat nu twee projecten:

  • HalloWereld. Dit is het toepassingsproject dat uw services bevat. Het bevat ook het toepassingsmanifest dat de toepassing beschrijft, evenals een aantal PowerShell-scripts die u helpen bij het implementeren van uw toepassing.
  • 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-eindpuntmethode, RunAsync genaamd, waar u alle workloads kunt uitvoeren, inclusief langlopende rekenworkloads.
protected override async Task RunAsync(CancellationToken cancellationToken)
{
    ...
}
  • Een communicatie-ingangspunt waar u de gewenste communicatiestack kunt aansluiten, zoals ASP.NET Core. Hier kunt u aanvragen van gebruikers en andere services gaan ontvangen.
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    ...
}

In deze zelfstudie richten we ons op de RunAsync() ingangsmethode. Hier kunt u direct beginnen met het uitvoeren van uw code. De projectsjabloon bevat een voorbeeld van een implementatie waarmee RunAsync() een doorlopend aantal wordt verhoogd.

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 eenvoudigweg 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 verschillende oorzaken hebben, 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, zodat de runtime kan worden voortgezet. 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 met Task.Run() in uw RunAsync implementatie.

Annulering van uw workload is een gezamenlijke inspanning die wordt beheerd door het opgegeven annuleringstoken. Het systeem wacht totdat uw taak is beëindigd (na voltooiing, annulering of fout) voordat het doorgaat. Het is belangrijk dat u het annuleringstoken respecteert, eventuele werkzaamheden voltooit en zo snel mogelijk afsluit 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 gestart, 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, in combinatie met de code die deze gebruikt. Status wordt maximaal beschikbaar gemaakt door Service Fabric zonder dat de status hoeft te worden bewaard in een extern archief.

Als u een tellerwaarde wilt converteren van staatloos naar maximaal beschikbaar en permanent, zelfs wanneer de service wordt verplaatst of opnieuw wordt gestart, hebt u een stateful service nodig.

In dezelfde HelloWorld-toepassing kunt u een nieuwe service toevoegen door met de rechtermuisknop op de servicesverwijzingen in het toepassingsproject te klikken en Toevoegen -> Nieuwe Service Fabric-service te selecteren.

Een service toevoegen aan uw Service Fabric-toepassing

Selecteer .NET Core 2.0 -> Stateful Service en noem deze HelloWorldStateful. Klik op OK.

Het dialoogvenster Nieuw project gebruiken om een nieuwe stateful Service Fabric-service te maken

Uw toepassing moet nu twee services hebben: de stateless service HelloWorldStateless en de stateful service HelloWorldStateful.

Een stateful service heeft dezelfde toegangspunten als een stateless service. Het belangrijkste verschil is de beschikbaarheid van een statusprovider die status betrouwbaar kan opslaan. Service Fabric wordt geleverd met een implementatie van de statusprovider 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, dat 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 extra werk namens u uit voordat het wordt RunAsync()uitgevoerd. Dit kan onder andere zijn om ervoor te zorgen dat Reliable State Manager en Reliable Collections klaar zijn voor gebruik.

Betrouwbare verzamelingen en 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 externe permanente opslag 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 beperkingen:

  • Service Fabric maakt uw status maximaal beschikbaar door de status op verschillende knooppunten te repliceren . Betrouwbare verzamelingen slaan uw gegevens op op de lokale schijf op elke replica. Dit betekent dat alles wat is opgeslagen in Betrouwbare verzamelingen 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 standaardserialisatie 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 van 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 voor 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 Reliable Collections voor u. U kunt de Reliable State Manager op elk gewenst moment en op elke plaats in uw service om een betrouwbare verzameling op naam vragen. Reliable State Manager zorgt ervoor dat u een verwijzing terugkrijgt. Het is niet raadzaam om verwijzingen naar betrouwbare verzamelingsexemplaren op te slaan in variabelen of eigenschappen van klasseleden. Zorg ervoor dat de verwijzing te allen tijde in de levenscyclus van de service is ingesteld op een exemplaar. Reliable State Manager verwerkt dit werk voor u en is geoptimaliseerd voor herhaalde bezoeken.

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();
}

Reliable Collections hebben veel van dezelfde bewerkingen als hun System.Collections.Generic tegenhangers en System.Collections.Concurrent , 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 te repliceren en op schijf te behouden.

Betrouwbare verzamelingsbewerkingen zijn transactioneel, zodat u de status consistent kunt houden voor 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 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 keren 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 gestart, kunt u de gegenereerde ETW-gebeurtenissen (Event Tracing for Windows) weergeven in een venster met 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 handleiding Aan de slag voor informatie over het instellen van uw lokale omgeving.

Diagnostische gebeurtenissen weergeven in Visual Studio

Volgende stappen

Fouten opsporen in uw Service Fabric-toepassing in Visual Studio

Aan de slag: Service Fabric-web-API-services met OWIN-self-hosting

Meer informatie over Betrouwbare verzamelingen

Een app implementeren

Toepassingsupgrade

Referentie voor ontwikkelaars voor Reliable Services