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ą usługę Reliable Service.

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 on definiowany StatelessService przez klasę, która rozszerza się, oraz wszelkie inne kod lub zależności użyte tam 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 ciągu "fabric:/" schemat, taki jak "fabric:/MyApp/MyService".
  • Host usługi: utworzone wystąpienia usługi 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 uznawana za bezstanową, ponieważ sama usługa nie zawiera danych, które muszą być przechowywane niezawodnie ani udostępniane o wysokiej dostępności. Jeśli wystąpienie usługi bezstanowej zostanie zamknięte, cały jej stan wewnętrzny zostanie utracony. W tym typie usługi stan musi być utrwalone w magazynie zewnętrznym, takim jak tabele platformy Azure lub SQL Database, aby 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

Twoje rozwiązanie zawiera teraz dwa projekty:

  • HelloWorld. Jest to projekt aplikacji zawierający usługi. Zawiera również manifest aplikacji, który opisuje 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() , która zwiększa liczbę kroczącą.

Uwaga

Aby uzyskać szczegółowe informacje o sposobie pracy z stosem komunikacji, zobacz Komunikacja z usługą za pomocą 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 całym okresie istnienia usługi. 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 uaktualniana.
  • Podstawowy sprzęt doświadcza awarii.

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 poczekać na wszelkie długotrwałe lub blokujące operacje, aby umożliwić kontynuowanie środowiska uruchomieniowego. Uwaga w pętli w while(true) poprzednim przykładzie jest używana funkcja zwracania await Task.Delay() zadań. Jeśli obciążenie musi być blokowane synchronicznie, należy zaplanować nowe zadanie Task.Run() w implementacji RunAsync .

Anulowanie obciążenia to wspólny wysiłek zaplanowany 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 uhonorować token anulowania, zakończyć pracę i zamknąć RunAsync() tak szybko, jak to możliwe, gdy system żąda anulowania.

W tym przykładzie usługi bezstanowej liczba jest przechowywana w zmiennej lokalnej. Ponieważ jest to usługa bezstanowa, wartość przechowywana 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 samej usłudze, współlokacyjnie 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, potrzebna jest usługa stanowa.

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 pozycję 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ą usługi Reliable State Manager. Stanowa usługa Reliable Service domyślnie używa tego dostawcy stanu.

Otwórz plik HelloWorldStateful.cs w pliku HelloWorldStateful, który 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, że niezawodne usługi State Manager i Reliable Collections są gotowe do użycia.

Niezawodne kolekcje i niezawodny menedżer stanu

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. Dzięki usługom Service Fabric i Reliable Collections można przechowywać dane bezpośrednio w usłudze bez konieczności zewnętrznego trwałego magazynu. Niezawodne kolekcje zapewniają 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 mogą przechowywać dowolny typ platformy .NET, w tym typy niestandardowe, z kilkoma zastrzeżeniami:

  • Usługa Service Fabric zapewnia wysoką dostępność, replikując stan między węzłami, a kolekcje Reliable Collections przechowują dane na dysku lokalnym na każdej repliki. Oznacza to, że wszystko, co jest przechowywane w kolekcjach Reliable Collections, musi być serializowalne. Domyślnie usługi 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 korzystania z domyślnego serializatora.

  • Obiekty są replikowane w celu zapewnienia wysokiej dostępności podczas zatwierdzania transakcji w kolekcjach Reliable Collections. Obiekty przechowywane w kolekcjach Reliable Collections 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.

Usługa Reliable State Manager zarządza kolekcjami Reliable Collections. Możesz po prostu poprosić reliable state Manager o niezawodną kolekcję według nazwy w dowolnym momencie i w dowolnym miejscu w usłudze. Usługa Reliable State Manager zapewnia, ż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 upewnić się, że odwołanie jest ustawione na wystąpienie przez cały czas w cyklu życia usługi. Usługa Reliable State Manager obsługuje tę pracę i jest zoptymalizowana pod kątem powtarzających się 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 Mają wiele tych samych operacji, które wykonują i System.Collections.GenericSystem.Collections.Concurrent ich odpowiedniki, z wyjątkiem zapytań zintegrowanych z językiem (LINQ). Operacje na kolekcjach Reliable Collections są asynchroniczne. Dzieje się tak, ponieważ operacje zapisu w kolekcjach Reliable Collection 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 kolekcjach i operacjach niezawodnych. Na przykład można usunąć kolejkę elementu roboczego z kolejki niezawodnej, wykonać na nim operację i zapisać wynik w słowniku Reliable, wszystkie 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 zakończeniu kolejki elementu wystąpi błąd, ale przed zapisaniem wyniku cała transakcja zostanie wycofana, a element pozostanie w kolejce do przetworzenia.

Uruchamianie aplikacji

Wrócimy teraz do aplikacji HelloWorld . Teraz możesz tworzyć i wdrażać usługi. Po naciśnięciu klawisza 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 wiadomości, rozwijając tę wiadomość.

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

Uaktualnianie aplikacji

Dokumentacja dla deweloperów dotycząca usług Reliable Services