Kom igång med Reliable Services

Ett Azure Service Fabric-program innehåller en eller flera tjänster som kör koden. Den här guiden visar hur du skapar både tillståndslösa och tillståndskänsliga Service Fabric-program med Reliable Services.

På den här sidan finns en träningsvideo som också visar hur du skapar en tillståndslös Reliable-tjänst.

Grundläggande begrepp

För att komma igång med Reliable Services behöver du bara förstå några grundläggande begrepp:

  • Tjänsttyp: Det här är din tjänstimplementering. Den definieras av den klass som du skriver som utökar StatelessService och andra kod- eller beroenden som används däri, tillsammans med ett namn och ett versionsnummer.
  • Namngiven tjänstinstans: Om du vill köra tjänsten skapar du namngivna instanser av din tjänsttyp, ungefär som du skapar objektinstanser av en klasstyp. En tjänstinstans har ett namn i form av en URI med "fabric:/" schema, till exempel "fabric:/MyApp/MyService".
  • Tjänstvärd: De namngivna tjänstinstanser som du skapar måste köras i en värdprocess. Tjänstvärden är bara en process där instanser av tjänsten kan köras.
  • Tjänstregistrering: Registreringen sammanför allt. Tjänsttypen måste registreras med Service Fabric-körningen i en tjänstvärd för att Service Fabric ska kunna skapa instanser av den för att kunna köras.

Skapa en tillståndslös tjänst

En tillståndslös tjänst är en typ av tjänst som för närvarande är normen i molnprogram. Den anses vara tillståndslös eftersom själva tjänsten inte innehåller data som behöver lagras på ett tillförlitligt sätt eller som har hög tillgänglighet. Om en instans av en tillståndslös tjänst stängs av går allt dess interna tillstånd förlorat. I den här typen av tjänst måste tillståndet bevaras i ett externt arkiv, till exempel Azure-tabeller eller SQL Database, för att det ska göras mycket tillgängligt och tillförlitligt.

Starta Visual Studio 2017 eller Visual Studio 2019 som administratör och skapa ett nytt Service Fabric-programprojekt med namnet HelloWorld:

Använd dialogrutan Nytt projekt för att skapa ett nytt Service Fabric-program

Skapa sedan ett tillståndslöst tjänstprojekt med .NET Core 2.0 med namnet HelloWorldStateless:

I den andra dialogrutan skapar du ett tillståndslöst tjänstprojekt

Din lösning innehåller nu två projekt:

  • HelloWorld. Det här är programprojektet som innehåller dina tjänster. Den innehåller även programmanifestet som beskriver programmet, samt ett antal PowerShell-skript som hjälper dig att distribuera ditt program.
  • HelloWorldStateless. Det här är tjänstprojektet. Den innehåller den tillståndslösa tjänstimplementeringen.

Implementera tjänsten

Öppna filen HelloWorldStateless.cs i tjänstprojektet. I Service Fabric kan en tjänst köra vilken affärslogik som helst. Tjänst-API:et innehåller två startpunkter för koden:

  • En öppen startpunktsmetod som kallas RunAsync, där du kan börja köra alla arbetsbelastningar, inklusive långvariga beräkningsarbetsbelastningar.
protected override async Task RunAsync(CancellationToken cancellationToken)
{
    ...
}
  • En kommunikationsstartpunkt där du kan koppla in din kommunikationsstack, till exempel ASP.NET Core. Här kan du börja ta emot begäranden från användare och andra tjänster.
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    ...
}

I den här självstudien RunAsync() fokuserar vi på startpunktsmetoden. Det är här du omedelbart kan börja köra koden. Projektmallen innehåller en exempelimplementering av RunAsync() som ökar ett rullande antal.

Anteckning

Mer information om hur du arbetar med en kommunikationsstack finns i Tjänstkommunikation med ASP.NET Core

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

Plattformen anropar den här metoden när en instans av en tjänst placeras och är redo att köras. För en tillståndslös tjänst innebär det helt enkelt när tjänstinstansen öppnas. En annulleringstoken tillhandahålls för att samordna när din tjänstinstans måste stängas. I Service Fabric kan den här öppna/stäng-cykeln för en tjänstinstans inträffa många gånger under hela tjänstens livslängd. Detta kan inträffa av olika skäl, till exempel:

  • Systemet flyttar dina tjänstinstanser för resursutjämning.
  • Fel uppstår i koden.
  • Programmet eller systemet uppgraderas.
  • Den underliggande maskinvaran upplever ett avbrott.

Den här orkestreringen hanteras av systemet för att hålla din tjänst högtillgänglig och korrekt balanserad.

RunAsync() bör inte blockera synkront. Din implementering av RunAsync bör returnera en aktivitet eller vänta på långvariga eller blockerande åtgärder så att körningen kan fortsätta. Observera i loopen while(true) i föregående exempel att en uppgiftsretur await Task.Delay() används. Om arbetsbelastningen måste blockeras synkront bör du schemalägga en ny uppgift med Task.Run() i implementeringen RunAsync .

Annulleringen av din arbetsbelastning är en samarbetsinsats som samordnas av den angivna annulleringstoken. Systemet väntar på att aktiviteten ska avslutas (genom slutförande, annullering eller fel) innan den går vidare. Det är viktigt att respektera annulleringstoken, slutföra allt arbete och avsluta RunAsync() så snabbt som möjligt när systemet begär annullering.

I det här tillståndslösa tjänstexemplet lagras antalet i en lokal variabel. Men eftersom det här är en tillståndslös tjänst finns värdet som lagras bara för den aktuella livscykeln för tjänstinstansen. När tjänsten flyttas eller startas om går värdet förlorat.

Skapa en tillståndskänslig tjänst

Service Fabric introducerar en ny typ av tjänst som är tillståndskänslig. En tillståndskänslig tjänst kan upprätthålla tillståndet på ett tillförlitligt sätt inom själva tjänsten, tillsammans med koden som använder den. Tillståndet görs högtillgängligt av Service Fabric utan att behöva bevara tillståndet för ett externt arkiv.

Om du vill konvertera ett räknarvärde från tillståndslöst till högtillgängligt och beständigt, även när tjänsten flyttas eller startas om, behöver du en tillståndskänslig tjänst.

I samma HelloWorld-program kan du lägga till en ny tjänst genom att högerklicka på tjänstreferenserna i programprojektet och välja Lägg till –> ny Service Fabric Service.

Lägga till en tjänst i Service Fabric-programmet

Välj .NET Core 2.0 –> Tillståndskänslig tjänst och ge den namnet HelloWorldStateful. Klicka på OK.

Använd dialogrutan Nytt projekt för att skapa en ny tillståndskänslig Service Fabric-tjänst

Ditt program bör nu ha två tjänster: den tillståndslösa tjänsten HelloWorldStateless och den tillståndskänsliga tjänsten HelloWorldStateful.

En tillståndskänslig tjänst har samma startpunkter som en tillståndslös tjänst. Den största skillnaden är tillgängligheten för en tillståndsprovider som kan lagra tillståndet på ett tillförlitligt sätt. Service Fabric levereras med en implementering av tillståndsprovidern med namnet Reliable Collections, som gör att du kan skapa replikerade datastrukturer via Reliable State Manager. En tillståndskänslig Reliable Service använder den här tillståndsprovidern som standard.

Öppna HelloWorldStateful.cs i HelloWorldStateful, som innehåller följande RunAsync-metod:

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() fungerar på samma sätt i tillståndskänsliga och tillståndslösa tjänster. Men i en tillståndskänslig tjänst utför plattformen ytterligare arbete åt dig innan den kör RunAsync(). Det här arbetet kan omfatta att se till att Reliable State Manager och Reliable Collections är redo att användas.

Reliable Collections och Reliable State Manager

var myDictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<string, long>>("myDictionary");

IReliableDictionary är en ordlisteimplementering som du kan använda för att lagra tillståndet i tjänsten på ett tillförlitligt sätt. Med Service Fabric och Reliable Collections kan du lagra data direkt i tjänsten utan att behöva ett externt beständigt arkiv. Reliable Collections ger dina data hög tillgänglighet. Service Fabric gör detta genom att skapa och hantera flera repliker av tjänsten åt dig. Det tillhandahåller också ett API som abstraherar bort komplexiteten i hanteringen av dessa repliker och deras tillståndsövergångar.

Reliable Collections kan lagra valfri .NET-typ, inklusive dina anpassade typer, med några varningar:

  • Service Fabric ger ditt tillstånd hög tillgänglighet genom att replikera tillstånd mellan noder och Reliable Collections lagrar dina data på en lokal disk på varje replik. Det innebär att allt som lagras i Reliable Collections måste vara serialiserbart. Som standard använder Reliable Collections DataContract för serialisering, så det är viktigt att se till att dina typer stöds av Data Contract Serializer när du använder standard-serialiseraren.

  • Objekt replikeras för hög tillgänglighet när du genomför transaktioner i Reliable Collections. Objekt som lagras i Reliable Collections lagras i lokalt minne i tjänsten. Det innebär att du har en lokal referens till objektet.

    Det är viktigt att du inte muterar lokala instanser av dessa objekt utan att utföra en uppdateringsåtgärd på den tillförlitliga samlingen i en transaktion. Det beror på att ändringar i lokala instanser av objekt inte replikeras automatiskt. Du måste infoga objektet i ordlistan igen eller använda någon av uppdateringsmetoderna i ordlistan.

Reliable State Manager hanterar Reliable Collections åt dig. Du kan bara be Reliable State Manager om en tillförlitlig samling med namn när som helst och på valfri plats i din tjänst. Reliable State Manager ser till att du får tillbaka en referens. Vi rekommenderar inte att du sparar referenser till tillförlitliga samlingsinstanser i klassmedlemsvariabler eller egenskaper. Särskild försiktighet måste iakttas för att säkerställa att referensen alltid är inställd på en instans i tjänstens livscykel. Reliable State Manager hanterar det här arbetet åt dig och är optimerat för upprepade besök.

Transaktionella och asynkrona åtgärder

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 har många av de åtgärder som deras System.Collections.Generic och System.Collections.Concurrent motsvarigheterna utför, förutom LINQ (Language Integrated Query). Åtgärder på Reliable Collections är asynkrona. Det beror på att skrivåtgärder med Reliable Collections utför I/O-åtgärder för att replikera och spara data till disk.

Reliable Collection-åtgärder är transaktionella, så att du kan hålla statusen konsekvent över flera Tillförlitliga samlingar och åtgärder. Du kan till exempel dequeue ett arbetsobjekt från en Reliable Queue, utföra en åtgärd på den och spara resultatet i en Reliable Dictionary, allt inom en enda transaktion. Detta behandlas som en atomisk åtgärd och garanterar att hela åtgärden lyckas eller att hela åtgärden återställs. Om ett fel uppstår efter att du har lagt objektet i kö men innan du sparar resultatet återställs hela transaktionen och objektet finns kvar i kön för bearbetning.

Kör programmet

Nu återgår vi till HelloWorld-programmet . Nu kan du skapa och distribuera dina tjänster. När du trycker på F5 skapas och distribueras programmet till det lokala klustret.

När tjänsterna har börjat köras kan du visa de genererade händelsespårningshändelserna för Windows (ETW) i ett fönster med diagnostikhändelser . Observera att händelserna som visas kommer från både den tillståndslösa tjänsten och den tillståndskänsliga tjänsten i programmet. Du kan pausa strömmen genom att klicka på pausknappen . Du kan sedan granska information om ett meddelande genom att expandera meddelandet.

Anteckning

Innan du kör programmet kontrollerar du att du har ett lokalt utvecklingskluster som körs. Läs kom igång-guiden för information om hur du konfigurerar din lokala miljö.

Visa diagnostikhändelser i Visual Studio

Nästa steg

Felsöka ditt Service Fabric-program i Visual Studio

Kom igång: Service Fabric Web API-tjänster med självvärdtjänst i OWIN

Läs mer om Reliable Collections

Distribuera ett program

Programuppgradering

Referens för utvecklare för Reliable Services