Partition Service Fabric reliable services (Partycjonowanie usług Reliable Services w ramach usługi Service Fabric)

Ten artykuł zawiera wprowadzenie do podstawowych pojęć dotyczących partycjonowania niezawodnych usług usługi Azure Service Fabric. Partycjonowanie umożliwia przechowywanie danych na maszynach lokalnych, dzięki czemu dane i obliczenia można skalować razem.

Porada

Kompletny przykład kodu w tym artykule jest dostępny w witrynie GitHub.

Partycjonowanie

Partycjonowanie nie jest unikatowe dla usługi Service Fabric. W rzeczywistości jest to podstawowy wzorzec tworzenia skalowalnych usług. W szerszym sensie możemy myśleć o partycjonowaniu jako koncepcji dzielenia stanu (danych) i obliczeń na mniejsze dostępne jednostki w celu zwiększenia skalowalności i wydajności. Znaną formą partycjonowania jest partycjonowanie danych, nazywane również fragmentowaniem.

Partycjonowanie usług bezstanowych usługi Service Fabric

W przypadku usług bezstanowych można myśleć o partycji będącej jednostką logiczną zawierającą co najmniej jedno wystąpienie usługi. Rysunek 1 przedstawia usługę bezstanową z pięcioma wystąpieniami rozproszonymi w klastrze przy użyciu jednej partycji.

Usługa bezstanowa

Istnieją naprawdę dwa typy rozwiązań usługi bezstanowej. Pierwsza z nich to usługa, która utrzymuje stan zewnętrznie, na przykład w bazie danych w usłudze Azure SQL Database (na przykład w witrynie internetowej, która przechowuje informacje o sesji i dane). Drugi to usługi tylko do obliczeń (takie jak kalkulator lub miniatury obrazów), które nie zarządzają żadnym stanem trwałym.

W obu przypadkach partycjonowanie usługi bezstanowej jest bardzo rzadką skalowalnością, a dostępność jest zwykle osiągana przez dodanie większej liczby wystąpień. Jedynym momentem, w którym chcesz rozważyć wiele partycji dla wystąpień usługi bezstanowej, jest to, że konieczne jest spełnienie specjalnych żądań routingu.

Rozważmy na przykład przypadek, w którym użytkownicy z identyfikatorami w określonym zakresie powinni być obsługiwani tylko przez określone wystąpienie usługi. Innym przykładem partycjonowania usługi bezstanowej jest to, że w usłudze zaplecza z podziałem na partycje (np. baza danych podzielona na fragmenty w SQL Database) i chcesz kontrolować, które wystąpienie usługi powinno być zapisywane w bazie danych, lub wykonać inną pracę przygotowania w usłudze bezstanowej, która wymaga tych samych informacji partycjonowania, które są używane w zapleczu. Te typy scenariuszy można również rozwiązać na różne sposoby i niekoniecznie wymagają partycjonowania usługi.

Pozostała część tego przewodnika koncentruje się na usługach stanowych.

Partycjonowanie usług stanowych usługi Service Fabric

Usługa Service Fabric ułatwia opracowywanie skalowalnych usług stanowych, oferując pierwszoklasowy sposób partycjonowania stanu (danych). Koncepcyjnie można pomyśleć o partycji usługi stanowej jako jednostki skalowania, która jest wysoce niezawodna za pośrednictwem replik rozproszonych i zrównoważonych między węzłami w klastrze.

Partycjonowanie w kontekście usług stanowych usługi Service Fabric odnosi się do procesu określania, że określona partycja usługi jest odpowiedzialna za część pełnego stanu usługi. (Jak wspomniano wcześniej, partycja jest zestawem replik). Świetną rzeczą w usłudze Service Fabric jest umieszczenie partycji w różnych węzłach. Dzięki temu mogą one rosnąć do limitu zasobów węzła. Wraz ze wzrostem potrzeb dotyczących danych partycje rosną, a usługa Service Fabric ponownie równoważy partycje między węzłami. Zapewnia to ciągłe efektywne wykorzystanie zasobów sprzętowych.

Aby nadać przykład, załóżmy, że zaczynasz od klastra 5-węzłowego i usługi skonfigurowanej do posiadania 10 partycji i elementu docelowego trzech replik. W takim przypadku usługa Service Fabric równoważy i dystrybuuje repliki w klastrze — a w końcu dwie repliki podstawowe na węzeł. Jeśli teraz musisz skalować klaster do 10 węzłów, usługa Service Fabric będzie ponownie równoważyć repliki podstawowe we wszystkich 10 węzłach . Podobnie w przypadku skalowania z powrotem do 5 węzłów usługa Service Fabric będzie ponownie równoważyć wszystkie repliki w 5 węzłach.

Rysunek 2 przedstawia rozkład 10 partycji przed skalowaniem klastra i po nim.

Usługa stanowa

W związku z tym skalowanie w poziomie jest osiągane, ponieważ żądania klientów są dystrybuowane na komputerach, ogólna wydajność aplikacji jest większa, a rywalizacja o dostęp do fragmentów danych jest ograniczona.

Planowanie partycjonowania

Przed wdrożeniem usługi należy zawsze wziąć pod uwagę strategię partycjonowania wymaganą do skalowania w poziomie. Istnieją różne sposoby, ale wszystkie z nich koncentrują się na tym, co aplikacja musi osiągnąć. W kontekście tego artykułu rozważmy niektóre z ważniejszych aspektów.

Dobrym podejściem jest zastanowienie się nad strukturą stanu, który musi być podzielony na partycje, jako pierwszy krok.

Weźmy prosty przykład. Jeśli chcesz utworzyć usługę dla ankiety dla całego powiatu, możesz utworzyć partycję dla każdego miasta w hrabstwie. Następnie można przechowywać głosy dla każdej osoby w mieście w partycji, która odpowiada tej miejscowości. Rysunek 3 ilustruje zestaw osób i miasto, w którym się znajdują.

Prosta partycja

Ponieważ populacja miast różni się szeroko, może się skończyć z niektórymi partycjami, które zawierają dużo danych (np. Seattle) i inne partycje z bardzo małym stanem (np. Kirkland). Jaki jest więc wpływ na partycje o nierównych ilościach stanu?

Jeśli pomyślisz o przykładzie ponownie, możesz łatwo zobaczyć, że partycja, która posiada głosy dla Seattle, uzyska więcej ruchu niż Kirkland. Domyślnie usługa Service Fabric zapewnia, że w każdym węźle znajduje się mniej więcej ta sama liczba replik podstawowych i pomocniczych. Dlatego można skończyć z węzłami, które przechowują repliki, które obsługują większy ruch, a inne, które obsługują mniej ruchu. Najlepiej, aby uniknąć gorących i zimnych punktów, takich jak to w klastrze.

Aby tego uniknąć, należy wykonać dwie czynności z punktu widzenia partycjonowania:

  • Spróbuj podzielić stan na partycje, aby był równomiernie rozłożony na wszystkie partycje.
  • Ładowanie raportów z każdej repliki dla usługi. (Aby uzyskać informacje na temat sposobu, zapoznaj się z tym artykułem dotyczącym metryk i ładowania). Usługa Service Fabric umożliwia raportowanie obciążenia zużywanego przez usługi, takie jak ilość pamięci lub liczba rekordów. Na podstawie zgłoszonych metryk usługa Service Fabric wykrywa, że niektóre partycje obsługują wyższe obciążenia niż inne i ponownie równoważą klaster, przenosząc repliki do bardziej odpowiednich węzłów, dzięki czemu ogólny brak przeciążenia węzła.

Czasami nie można wiedzieć, ile danych będzie znajdować się w danej partycji. W związku z tym ogólne zalecenie polega na tym, aby wykonać obie czynności, przyjmując strategię partycjonowania, która równomiernie rozkłada dane na partycje, a po drugie przez raportowanie obciążenia. Pierwsza metoda uniemożliwia sytuacje opisane w przykładzie głosowania, podczas gdy druga pomaga wygładzić tymczasowe różnice w dostępie lub obciążeniu w czasie.

Innym aspektem planowania partycji jest wybranie odpowiedniej liczby partycji, od których chcesz zacząć. Z perspektywy usługi Service Fabric nie ma nic, co uniemożliwia rozpoczęcie pracy z większą liczbą partycji niż oczekiwano w danym scenariuszu. W rzeczywistości przy założeniu, że maksymalna liczba partycji jest prawidłową metodą.

W rzadkich przypadkach może być potrzebnych więcej partycji, niż początkowo wybrano. Ponieważ nie można zmienić liczby partycji po fakcie, należy zastosować pewne zaawansowane podejścia do partycji, takie jak utworzenie nowego wystąpienia usługi tego samego typu usługi. Należy również zaimplementować logikę po stronie klienta, która kieruje żądania do poprawnego wystąpienia usługi w oparciu o wiedzę po stronie klienta, którą musi zachować kod klienta.

Innym czynnikiem do planowania partycjonowania jest dostępne zasoby komputera. Ponieważ stan musi być dostępny i przechowywany, należy wykonać następujące czynności:

  • Limity przepustowości sieci
  • Limity pamięci systemowej
  • Limity magazynu dysku

Więc co się stanie, jeśli wystąpią ograniczenia zasobów w uruchomionym klastrze? Odpowiedź polega na tym, że można po prostu skalować klaster w poziomie, aby spełnić nowe wymagania.

Przewodnik planowania pojemności zawiera wskazówki dotyczące określania liczby węzłów, których potrzebuje klaster.

Wprowadzenie do partycjonowania

W tej sekcji opisano, jak rozpocząć partycjonowanie usługi.

Usługa Service Fabric oferuje wybór trzech schematów partycji:

  • Partycjonowanie zakresowe (inaczej znane jako UniformInt64Partition).
  • Nazwane partycjonowanie. Aplikacje korzystające z tego modelu zwykle mają dane, które można zasobnikować w powiązanym zestawie. Niektóre typowe przykłady pól danych używanych jako nazwane klucze partycji to regiony, kody pocztowe, grupy klientów lub inne granice biznesowe.
  • Partycjonowanie jednotonowe. Partycje pojedyncze są zwykle używane, gdy usługa nie wymaga dodatkowego routingu. Na przykład usługi bezstanowe domyślnie używają tego schematu partycjonowania.

Schematy partycjonowania nazwane i jednotonowe są specjalnymi formami partycji zakresowych. Domyślnie szablony programu Visual Studio dla usługi Service Fabric używają partycjonowania w zakresie, ponieważ jest to najbardziej typowe i przydatne. W pozostałej części tego artykułu skupiono się na schemacie partycjonowania zakresu.

Schemat partycjonowania w zakresie

Służy do określania zakresu liczby całkowitej (identyfikowanego przez niski klucz i wysoki klucz) oraz wielu partycji (n). Tworzy n partycji, z których każda jest odpowiedzialna za nienakładanie się podzbięć ogólnego zakresu kluczy partycji. Na przykład schemat partycjonowania o zakresie z niskim kluczem 0, kluczem wysokim 99 i liczbą 4 tworzy cztery partycje, jak pokazano poniżej.

Partycjonowanie zakresu

Typowym podejściem jest utworzenie skrótu na podstawie unikatowego klucza w zestawie danych. Niektóre typowe przykłady kluczy to numer identyfikacyjny pojazdu (VIN), identyfikator pracownika lub unikatowy ciąg. Używając tego unikatowego klucza, wygenerujesz kod skrótu, moduluj zakres kluczy, aby użyć go jako klucza. Możesz określić górne i dolne granice dozwolonego zakresu kluczy.

Wybieranie algorytmu skrótu

Ważną częścią skrótu jest wybranie algorytmu skrótu. Należy wziąć pod uwagę, czy celem jest grupowanie podobnych kluczy w pobliżu siebie (rozróżnianie skrótów lokalnych) lub czy działanie powinno być szeroko dystrybuowane we wszystkich partycjach (skrót dystrybucji), co jest bardziej powszechne.

Cechy dobrego algorytmu tworzenia skrótów dystrybucji są takie, że łatwo jest obliczyć, ma kilka kolizji i równomiernie dystrybuuje klucze. Dobrym przykładem wydajnego algorytmu skrótu jest algorytm skrótu FNV-1 .

Dobrym zasobem dla ogólnych wyborów algorytmów kodu skrótu jest strona Wikipedii na funkcjach skrótu.

Tworzenie usługi stanowej z wieloma partycjami

Utwórzmy pierwszą niezawodną usługę stanową z wieloma partycjami. W tym przykładzie utworzysz bardzo prostą aplikację, w której chcesz przechowywać wszystkie nazwiska rozpoczynające się od tej samej litery w tej samej partycji.

Przed napisaniem kodu należy zastanowić się nad partycjami i kluczami partycji. Potrzebujesz 26 partycji (jeden dla każdej litery w alfabetu), ale co z niskimi i wysokimi kluczami? Ponieważ dosłownie chcemy mieć jedną partycję na literę, możemy użyć wartości 0 jako niskiego klucza i 25 jako klucza wysokiego, ponieważ każda litera jest własnym kluczem.

Uwaga

Jest to uproszczony scenariusz, ponieważ w rzeczywistości rozkład byłby nierówny. Nazwiska rozpoczynające się od liter "S" lub "M" są bardziej powszechne niż te rozpoczynające się od "X" lub "Y".

  1. Otwórznowy>projektw pliku>programu Visual Studio>.

  2. W oknie dialogowym Nowy projekt wybierz aplikację usługi Service Fabric.

  3. Wywołaj projekt "AlphabetPartitions".

  4. W oknie dialogowym Tworzenie usługi wybierz pozycję Usługa stanowa i wywołaj ją "Alphabet.Processing".

  5. Ustaw liczbę partycji. Otwórz plik ApplicationManifest.xml znajdujący się w folderze ApplicationPackageRoot projektu AlphabetPartitions i zaktualizuj parametr Processing_PartitionCount do 26, jak pokazano poniżej.

    <Parameter Name="Processing_PartitionCount" DefaultValue="26" />
    

    Należy również zaktualizować właściwości LowKey i HighKey elementu StatefulService w ApplicationManifest.xml, jak pokazano poniżej.

    <Service Name="Alphabet.Processing">
      <StatefulService ServiceTypeName="Alphabet.ProcessingType" TargetReplicaSetSize="[Processing_TargetReplicaSetSize]" MinReplicaSetSize="[Processing_MinReplicaSetSize]">
        <UniformInt64Partition PartitionCount="[Processing_PartitionCount]" LowKey="0" HighKey="25" />
      </StatefulService>
    </Service>    
    
  6. Aby usługa była dostępna, otwórz punkt końcowy na porcie, dodając element punktu końcowego ServiceManifest.xml (znajdujący się w folderze PackageRoot) dla usługi Alphabet.Processing, jak pokazano poniżej:

    <Endpoint Name="ProcessingServiceEndpoint" Port="8089" Protocol="http" Type="Internal" />
    

    Teraz usługa jest skonfigurowana do nasłuchiwania wewnętrznego punktu końcowego z 26 partycjami.

  7. Następnie należy zastąpić metodę CreateServiceReplicaListeners() klasy Processing.

    Uwaga

    W tym przykładzie przyjęto założenie, że używasz prostego elementu HttpCommunicationListener. Aby uzyskać więcej informacji na temat niezawodnej komunikacji z usługą, zobacz Model komunikacji usługi Reliable Service.

  8. Zalecanym wzorcem adresu URL, na którym nasłuchuje replika, jest następujący format: {scheme}://{nodeIp}:{port}/{partitionid}/{replicaid}/{guid}. Dlatego chcesz skonfigurować odbiornik komunikacji do nasłuchiwania prawidłowych punktów końcowych i z tym wzorcem.

    Wiele replik tej usługi może być hostowanych na tym samym komputerze, więc ten adres musi być unikatowy dla repliki. Dlatego identyfikator partycji i identyfikator repliki znajdują się w adresie URL. Program HttpListener może nasłuchiwać na wielu adresach na tym samym porcie, o ile prefiks adresu URL jest unikatowy.

    Dodatkowy identyfikator GUID jest dostępny dla zaawansowanego przypadku, w którym repliki pomocnicze również nasłuchują żądań tylko do odczytu. W takim przypadku należy upewnić się, że podczas przechodzenia z podstawowego do pomocniczego jest używany nowy unikatowy adres, aby wymusić ponowne rozpoznawanie adresu przez klientów. Element "+" jest używany jako adres tutaj, aby replika nasłuchuje na wszystkich dostępnych hostach (IP, FQDN, localhost itp.) Poniższy kod przedstawia przykład.

    protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
    {
         return new[] { new ServiceReplicaListener(context => this.CreateInternalListener(context))};
    }
    private ICommunicationListener CreateInternalListener(ServiceContext context)
    {
    
         EndpointResourceDescription internalEndpoint = context.CodePackageActivationContext.GetEndpoint("ProcessingServiceEndpoint");
         string uriPrefix = String.Format(
                "{0}://+:{1}/{2}/{3}-{4}/",
                internalEndpoint.Protocol,
                internalEndpoint.Port,
                context.PartitionId,
                context.ReplicaOrInstanceId,
                Guid.NewGuid());
    
         string nodeIP = FabricRuntime.GetNodeContext().IPAddressOrFQDN;
    
         string uriPublished = uriPrefix.Replace("+", nodeIP);
         return new HttpCommunicationListener(uriPrefix, uriPublished, this.ProcessInternalRequest);
    }
    

    Warto również zauważyć, że opublikowany adres URL różni się nieco od prefiksu adresu URL nasłuchiwania. Adres URL nasłuchiwania jest podawany do elementu HttpListener. Opublikowany adres URL to adres URL opublikowany w usłudze Service Fabric Naming Service, który jest używany do odnajdywania usług. Klienci będą prosić o ten adres za pośrednictwem tej usługi odnajdywania. Adres, który otrzymują klienci, musi mieć rzeczywisty adres IP lub nazwę FQDN węzła w celu nawiązania połączenia. Dlatego należy zastąpić ciąg "+" adresem IP węzła lub nazwą FQDN, jak pokazano powyżej.

  9. Ostatnim krokiem jest dodanie logiki przetwarzania do usługi, jak pokazano poniżej.

    private async Task ProcessInternalRequest(HttpListenerContext context, CancellationToken cancelRequest)
    {
        string output = null;
        string user = context.Request.QueryString["lastname"].ToString();
    
        try
        {
            output = await this.AddUserAsync(user);
        }
        catch (Exception ex)
        {
            output = ex.Message;
        }
    
        using (HttpListenerResponse response = context.Response)
        {
            if (output != null)
            {
                byte[] outBytes = Encoding.UTF8.GetBytes(output);
                response.OutputStream.Write(outBytes, 0, outBytes.Length);
            }
        }
    }
    private async Task<string> AddUserAsync(string user)
    {
        IReliableDictionary<String, String> dictionary = await this.StateManager.GetOrAddAsync<IReliableDictionary<String, String>>("dictionary");
    
        using (ITransaction tx = this.StateManager.CreateTransaction())
        {
            bool addResult = await dictionary.TryAddAsync(tx, user.ToUpperInvariant(), user);
    
            await tx.CommitAsync();
    
            return String.Format(
                "User {0} {1}",
                user,
                addResult ? "successfully added" : "already exists");
        }
    }
    

    ProcessInternalRequest Odczytuje wartości parametru ciągu zapytania używanego do wywołania partycji i wywołań AddUserAsync , aby dodać nazwisko do niezawodnego słownika dictionary.

  10. Dodajmy do projektu usługę bezstanową, aby zobaczyć, jak można wywołać określoną partycję.

    Ta usługa służy jako prosty interfejs internetowy, który akceptuje nazwisko jako parametr ciągu zapytania, określa klucz partycji i wysyła go do usługi Alphabet.Processing na potrzeby przetwarzania.

  11. W oknie dialogowym Tworzenie usługi wybierz pozycję Usługa bezstanowa i wywołaj ją "Alphabet.Web", jak pokazano poniżej.

    Zrzut ekranu usługi bezstanowej.

  12. Zaktualizuj informacje o punkcie końcowym w ServiceManifest.xml usługi Alphabet.WebApi, aby otworzyć port, jak pokazano poniżej.

    <Endpoint Name="WebApiServiceEndpoint" Protocol="http" Port="8081"/>
    
  13. Musisz zwrócić kolekcję elementów ServiceInstanceListeners w klasie Web. Ponownie możesz wdrożyć prosty element HttpCommunicationListener.

    protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
    {
        return new[] {new ServiceInstanceListener(context => this.CreateInputListener(context))};
    }
    private ICommunicationListener CreateInputListener(ServiceContext context)
    {
        // Service instance's URL is the node's IP & desired port
        EndpointResourceDescription inputEndpoint = context.CodePackageActivationContext.GetEndpoint("WebApiServiceEndpoint")
        string uriPrefix = String.Format("{0}://+:{1}/alphabetpartitions/", inputEndpoint.Protocol, inputEndpoint.Port);
        var uriPublished = uriPrefix.Replace("+", FabricRuntime.GetNodeContext().IPAddressOrFQDN);
        return new HttpCommunicationListener(uriPrefix, uriPublished, this.ProcessInputRequest);
    }
    
  14. Teraz musisz zaimplementować logikę przetwarzania. Element HttpCommunicationListener wywołuje żądanie ProcessInputRequest , gdy pojawi się żądanie. Więc przejdźmy do przodu i dodajmy poniższy kod.

    private async Task ProcessInputRequest(HttpListenerContext context, CancellationToken cancelRequest)
    {
        String output = null;
        try
        {
            string lastname = context.Request.QueryString["lastname"];
            char firstLetterOfLastName = lastname.First();
            ServicePartitionKey partitionKey = new ServicePartitionKey(Char.ToUpper(firstLetterOfLastName) - 'A');
    
            ResolvedServicePartition partition = await this.servicePartitionResolver.ResolveAsync(alphabetServiceUri, partitionKey, cancelRequest);
            ResolvedServiceEndpoint ep = partition.GetEndpoint();
    
            JObject addresses = JObject.Parse(ep.Address);
            string primaryReplicaAddress = (string)addresses["Endpoints"].First();
    
            UriBuilder primaryReplicaUriBuilder = new UriBuilder(primaryReplicaAddress);
            primaryReplicaUriBuilder.Query = "lastname=" + lastname;
    
            string result = await this.httpClient.GetStringAsync(primaryReplicaUriBuilder.Uri);
    
            output = String.Format(
                    "Result: {0}. <p>Partition key: '{1}' generated from the first letter '{2}' of input value '{3}'. <br>Processing service partition ID: {4}. <br>Processing service replica address: {5}",
                    result,
                    partitionKey,
                    firstLetterOfLastName,
                    lastname,
                    partition.Info.Id,
                    primaryReplicaAddress);
        }
        catch (Exception ex) { output = ex.Message; }
    
        using (var response = context.Response)
        {
            if (output != null)
            {
                output = output + "added to Partition: " + primaryReplicaAddress;
                byte[] outBytes = Encoding.UTF8.GetBytes(output);
                response.OutputStream.Write(outBytes, 0, outBytes.Length);
            }
        }
    }
    

    Przyjrzyjmy się jej krok po kroku. Kod odczytuje pierwszą literę parametru lastname ciągu zapytania do znaku. Następnie określa klucz partycji dla tej litery, odejmując wartość szesnastkowa od wartości A szesnastkowej pierwszej litery nazwiska.

    string lastname = context.Request.QueryString["lastname"];
    char firstLetterOfLastName = lastname.First();
    ServicePartitionKey partitionKey = new ServicePartitionKey(Char.ToUpper(firstLetterOfLastName) - 'A');
    

    Pamiętaj, że w tym przykładzie używamy 26 partycji z jednym kluczem partycji na partycję. Następnie uzyskamy partycję partition usługi dla tego klucza przy użyciu ResolveAsync metody w servicePartitionResolver obiekcie. servicePartitionResolver jest definiowany jako

    private readonly ServicePartitionResolver servicePartitionResolver = ServicePartitionResolver.GetDefault();
    

    Metoda ResolveAsync przyjmuje identyfikator URI usługi, klucz partycji i token anulowania jako parametry. Identyfikator URI usługi przetwarzania to fabric:/AlphabetPartitions/Processing. Następnie uzyskamy punkt końcowy partycji.

    ResolvedServiceEndpoint ep = partition.GetEndpoint()
    

    Na koniec utworzymy adres URL punktu końcowego oraz ciąg zapytania i wywołamy usługę przetwarzania.

    JObject addresses = JObject.Parse(ep.Address);
    string primaryReplicaAddress = (string)addresses["Endpoints"].First();
    
    UriBuilder primaryReplicaUriBuilder = new UriBuilder(primaryReplicaAddress);
    primaryReplicaUriBuilder.Query = "lastname=" + lastname;
    
    string result = await this.httpClient.GetStringAsync(primaryReplicaUriBuilder.Uri);
    

    Po zakończeniu przetwarzania zapisujemy dane wyjściowe z powrotem.

  15. Ostatnim krokiem jest przetestowanie usługi. Program Visual Studio używa parametrów aplikacji do wdrażania lokalnego i w chmurze. Aby przetestować usługę z 26 partycjami lokalnie, należy zaktualizować Local.xml plik w folderze ApplicationParameters projektu AlphabetPartitions, jak pokazano poniżej:

    <Parameters>
      <Parameter Name="Processing_PartitionCount" Value="26" />
      <Parameter Name="WebApi_InstanceCount" Value="1" />
    </Parameters>
    
  16. Po zakończeniu wdrażania możesz sprawdzić usługę i wszystkie jej partycje w Service Fabric Explorer.

    zrzut ekranu Service Fabric Explorer

  17. W przeglądarce możesz przetestować logikę partycjonowania, wprowadzając polecenie http://localhost:8081/?lastname=somename. Zobaczysz, że każde nazwisko rozpoczynające się od tej samej litery jest przechowywane w tej samej partycji.

    Zrzut ekranu przeglądarki

Kompletne rozwiązanie kodu używanego w tym artykule jest dostępne tutaj: https://github.com/Azure-Samples/service-fabric-dotnet-getting-started/tree/classic/Services/AlphabetPartitions.

Następne kroki

Dowiedz się więcej o usługach Service Fabric: