Udostępnij za pośrednictwem


Wprowadzenie do usług Reliable Services

Aplikacja usługi Azure Service Fabric zawiera co najmniej jedną usługę, która uruchamia kod. W tym przewodniku przedstawiono sposób tworzenia bezstanowych i stanowych aplikacji usługi Service Fabric za pomocą usług Reliable Services.

Sprawdź tę stronę, aby zapoznać się z filmem wideo szkoleniowym, w którym pokazano również, jak utworzyć bezstanową niezawodną usługę.

Podstawowe pojęcia

Aby rozpocząć pracę z usługami Reliable Services, musisz zrozumieć tylko kilka podstawowych pojęć:

  • Typ usługi: jest to implementacja usługi. Jest ona definiowana przez klasę, którą piszesz, która rozszerza StatelessService i dowolny inny kod lub zależności używane w nim, wraz z nazwą i numerem wersji.
  • Nazwane wystąpienie usługi: aby uruchomić usługę, należy utworzyć nazwane wystąpienia typu usługi, podobnie jak w przypadku tworzenia wystąpień obiektów typu klasy. Wystąpienie usługi ma nazwę w postaci identyfikatora URI przy użyciu schematu "fabric:/", takiego jak "fabric:/MyApp/MyService".
  • Host usługi: utworzone wystąpienia usługi o nazwie muszą być uruchamiane wewnątrz procesu hosta. Host usługi to tylko proces, w którym można uruchamiać wystąpienia usługi.
  • Rejestracja usługi: Rejestracja łączy wszystko razem. Typ usługi musi być zarejestrowany w środowisku uruchomieniowym usługi Service Fabric na hoście usługi, aby umożliwić usłudze Service Fabric tworzenie wystąpień do uruchomienia.

Tworzenie usługi bezstanowej

Usługa bezstanowa to typ usługi, która jest obecnie normą w aplikacjach w chmurze. Jest ona uważana za bezstanową, ponieważ sama usługa nie zawiera danych, które muszą być przechowywane niezawodnie lub zapewniają wysoką dostępność. Jeśli wystąpienie usługi bezstanowej zostanie zamknięte, cały stan wewnętrzny zostanie utracony. W tym typie usługi stan musi być utrwalone w magazynie zewnętrznym, takim jak tabele platformy Azure lub usługa SQL Database, aby można było zapewnić wysoką dostępność i niezawodność.

Uruchom program Visual Studio 2017 lub Visual Studio 2019 jako administrator i utwórz nowy projekt aplikacji usługi Service Fabric o nazwie HelloWorld:

Użyj okna dialogowego Nowy projekt, aby utworzyć nową aplikację usługi Service Fabric

Następnie utwórz projekt usługi bezstanowej przy użyciu platformy .NET Core 2.0 o nazwie HelloWorldStateless:

W drugim oknie dialogowym utwórz projekt usługi bezstanowej

Rozwiązanie zawiera teraz dwa projekty:

  • HelloWorld. Jest to projekt aplikacji, który zawiera usługi. Zawiera również manifest aplikacji opisujący aplikację, a także szereg skryptów programu PowerShell, które ułatwiają wdrażanie aplikacji.
  • HelloWorldStateless. Jest to projekt usługi. Zawiera on implementację usługi bezstanowej.

Implementowanie usługi

Otwórz plik HelloWorldStateless.cs w projekcie usługi. W usłudze Service Fabric usługa może uruchamiać dowolną logikę biznesową. Interfejs API usługi udostępnia dwa punkty wejścia dla kodu:

  • Otwarta metoda punktu wejścia o nazwie RunAsync, w której można rozpocząć wykonywanie dowolnych obciążeń, w tym długotrwałych obciążeń obliczeniowych.
protected override async Task RunAsync(CancellationToken cancellationToken)
{
    ...
}
  • Punkt wejścia komunikacji, w którym można podłączyć wybrany stos komunikacji, taki jak ASP.NET Core. W tym miejscu można rozpocząć odbieranie żądań od użytkowników i innych usług.
protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    ...
}

W tym samouczku skupimy się na metodzie RunAsync() punktu wejścia. W tym miejscu możesz natychmiast rozpocząć uruchamianie kodu. Szablon projektu zawiera przykładową implementację RunAsync() tego przyrostu liczby kroczącej.

Uwaga

Aby uzyskać szczegółowe informacje o sposobie pracy ze stosem komunikacyjnym, zobacz Komunikacja z usługą za pomocą platformy 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);
    }
}

Platforma wywołuje tę metodę, gdy zostanie umieszczone wystąpienie usługi i będzie gotowe do wykonania. W przypadku usługi bezstanowej oznacza to po prostu otwarcie wystąpienia usługi. Token anulowania jest udostępniany do koordynowania, gdy wystąpienie usługi musi zostać zamknięte. W usłudze Service Fabric ten cykl otwierania/zamykania wystąpienia usługi może wystąpić wiele razy w okresie istnienia usługi jako całości. Może się to zdarzyć z różnych powodów, w tym:

  • System przenosi wystąpienia usługi na potrzeby równoważenia zasobów.
  • Błędy występują w kodzie.
  • Aplikacja lub system jest uaktualniany.
  • Podstawowa awaria sprzętu.

Ta aranżacja jest zarządzana przez system w celu zapewnienia wysokiej dostępności i prawidłowego zrównoważenia usługi.

RunAsync() nie należy blokować synchronicznie. Implementacja narzędzia RunAsync powinna zwrócić zadanie lub oczekiwać na wszelkie długotrwałe lub blokujące operacje, aby umożliwić kontynuowanie działania środowiska uruchomieniowego. Zwróć uwagę na to, że while(true) w pętli w poprzednim przykładzie jest używane zwracanie await Task.Delay() zadań. Jeśli obciążenie musi być blokowane synchronicznie, należy zaplanować nowe zadanie w Task.Run() RunAsync implementacji.

Anulowanie obciążenia to nakład pracy współpracy zorganizowany przez podany token anulowania. System będzie czekać na zakończenie zadania (po pomyślnym zakończeniu, anulowaniu lub błędzie), zanim przejdzie dalej. Ważne jest, aby uczcić token anulowania, zakończyć pracę i zakończyć RunAsync() jak najszybciej, gdy system żąda anulowania.

W tym przykładzie usługi bezstanowej liczba jest przechowywana w zmiennej lokalnej. Ponieważ jest to usługa bezstanowa, przechowywana wartość istnieje tylko dla bieżącego cyklu życia wystąpienia usługi. Gdy usługa zostanie przeniesiona lub ponownie uruchomiona, wartość zostanie utracona.

Tworzenie usługi stanowej

Usługa Service Fabric wprowadza nowy rodzaj usługi, która jest stanowa. Usługa stanowa może niezawodnie obsługiwać stan w obrębie samej usługi, co-located z kodem, który go używa. Stan jest wysoce dostępny przez usługę Service Fabric bez konieczności utrwalania stanu w magazynie zewnętrznym.

Aby przekonwertować wartość licznika z bezstanowej na wysoce dostępną i trwałą, nawet jeśli usługa zostanie przeniesiona lub uruchomiona ponownie, potrzebujesz usługi stanowej.

W tej samej aplikacji HelloWorld możesz dodać nową usługę, klikając prawym przyciskiem myszy odwołania do usług w projekcie aplikacji i wybierając polecenie Dodaj —> nowa usługa Service Fabric.

Dodawanie usługi do aplikacji usługi Service Fabric

Wybierz pozycję .NET Core 2.0 —> stanowa usługa i nadaj jej nazwę HelloWorldStateful. Kliknij przycisk OK.

Użyj okna dialogowego Nowy projekt, aby utworzyć nową usługę stanową usługi Service Fabric

Aplikacja powinna teraz mieć dwie usługi: bezstanową usługę HelloWorldStateless i stanową usługę HelloWorldStateful.

Usługa stanowa ma te same punkty wejścia co usługa bezstanowa. Główną różnicą jest dostępność dostawcy stanu, który może niezawodnie przechowywać stan. Usługa Service Fabric jest dostarczana z implementacją dostawcy stanu o nazwie Reliable Collections, która umożliwia tworzenie zreplikowanych struktur danych za pomocą menedżera niezawodnego stanu. Stanowa usługa Reliable Service domyślnie używa tego dostawcy stanu.

Otwórz HelloWorldStateful.cs w funkcji HelloWorldStateful, która zawiera następującą metodę 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.

    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() działa podobnie w usługach stanowych i bezstanowych. Jednak w usłudze stanowej platforma wykonuje dodatkową pracę w Twoim imieniu przed wykonaniem RunAsync()polecenia . Ta praca może obejmować zapewnienie gotowości niezawodnych menedżerów stanów i niezawodnych kolekcji do użycia.

Reliable Collections and the Reliable State Manager

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

IReliableDictionary to implementacja słownika, której można użyć do niezawodnego przechowywania stanu w usłudze. Za pomocą usług Service Fabric i Reliable Collections można przechowywać dane bezpośrednio w usłudze bez konieczności zewnętrznego magazynu trwałego. Niezawodne kolekcje umożliwiają wysoką dostępność danych. Usługa Service Fabric umożliwia utworzenie wielu replik usługi i zarządzanie nimi. Udostępnia również interfejs API, który oddziela złożoność zarządzania tymi replikami i ich przejściami stanu.

Kolekcje Reliable Collections mogą przechowywać dowolny typ platformy .NET, w tym typy niestandardowe, z kilkoma zastrzeżeniami:

  • Usługa Service Fabric udostępnia stan wysokiej dostępności, replikując stan między węzłami, a kolekcje Reliable Collections przechowują dane na dysku lokalnym na każdej repliki. Oznacza to, że wszystkie elementy przechowywane w kolekcjach Reliable Collections muszą być serializowalne. Domyślnie kolekcje Reliable Collections używają elementu DataContract do serializacji, dlatego ważne jest, aby upewnić się, że typy są obsługiwane przez serializator kontraktu danych podczas używania domyślnego serializatora.

  • Obiekty są replikowane w celu zapewnienia wysokiej dostępności podczas zatwierdzania transakcji w niezawodnych kolekcjach. Obiekty przechowywane w niezawodnych kolekcjach są przechowywane w pamięci lokalnej w usłudze. Oznacza to, że masz lokalne odwołanie do obiektu.

    Ważne jest, aby nie mutować lokalnych wystąpień tych obiektów bez wykonywania operacji aktualizacji na niezawodnej kolekcji w transakcji. Dzieje się tak, ponieważ zmiany w lokalnych wystąpieniach obiektów nie będą replikowane automatycznie. Należy ponownie wstawić obiekt z powrotem do słownika lub użyć jednej z metod aktualizacji w słowniku.

Menedżer reliable state manager zarządza niezawodnymi kolekcjami. Możesz po prostu poprosić Menedżera niezawodnego stanu o niezawodną kolekcję według nazwy w dowolnym momencie i w dowolnym miejscu w usłudze. Niezawodny menedżer stanu gwarantuje, że otrzymasz odwołanie z powrotem. Nie zalecamy zapisywania odwołań do niezawodnych wystąpień kolekcji w zmiennych lub właściwościach składowych klasy. Należy zachować szczególną ostrożność, aby zapewnić, że odwołanie jest ustawione na wystąpienie przez cały czas w cyklu życia usługi. Niezawodny menedżer stanu obsługuje tę pracę dla Ciebie i jest zoptymalizowany pod kątem powtarzanych wizyt.

Operacje transakcyjne i asynchroniczne

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

Kolekcje Reliable Collections mają wiele tych samych operacji, które wykonują i System.Collections.Generic System.Collections.Concurrent ich odpowiedniki, z wyjątkiem zapytań zintegrowanych z językiem (LINQ). Operacje na kolekcjach Reliable Collections są asynchroniczne. Jest to spowodowane tym, że operacje zapisu w elementach Reliable Collections wykonują operacje we/wy w celu replikowania i utrwalania danych na dysku.

Operacje niezawodnej kolekcji są transakcyjne, dzięki czemu można zachować spójność stanu w wielu niezawodnych kolekcjach i operacjach. Na przykład można usunąć kolejkę elementu roboczego z kolejki niezawodnej, wykonać na niej operację i zapisać wynik w niezawodnym słowniku— wszystko w ramach jednej transakcji. Jest to traktowane jako operacja niepodzielna i gwarantuje, że cała operacja powiedzie się lub cała operacja zostanie wycofana. Jeśli po dequeue elementu wystąpi błąd, ale przed zapisaniem wyniku, cała transakcja zostanie wycofana, a element pozostanie w kolejce do przetworzenia.

Uruchamianie aplikacji

Teraz wracamy do aplikacji HelloWorld . Teraz możesz kompilować i wdrażać usługi. Po naciśnięciu F5 aplikacja zostanie skompilowana i wdrożona w klastrze lokalnym.

Po uruchomieniu usług można wyświetlić wygenerowane zdarzenia śledzenia zdarzeń systemu Windows (ETW) w oknie Zdarzenia diagnostyczne. Należy pamiętać, że wyświetlane zdarzenia pochodzą zarówno z usługi bezstanowej, jak i usługi stanowej w aplikacji. Strumień można wstrzymać, klikając przycisk Wstrzymaj. Następnie możesz sprawdzić szczegóły komunikatu, rozwijając ten komunikat.

Uwaga

Przed uruchomieniem aplikacji upewnij się, że jest uruchomiony lokalny klaster deweloperów. Zapoznaj się z przewodnikiem wprowadzającym, aby uzyskać informacje na temat konfigurowania środowiska lokalnego.

Wyświetlanie zdarzeń diagnostycznych w programie Visual Studio

Następne kroki

Debugowanie aplikacji usługi Service Fabric w programie Visual Studio

Wprowadzenie: Usługi internetowego interfejsu API usługi Service Fabric z samoobsługowym hostingiem OWIN

Dowiedz się więcej o kolekcjach Reliable Collections

Wdrażanie aplikacji

Uaktualnienie aplikacji

Dokumentacja dla deweloperów usług Reliable Services