Wprowadzenie do elementów Reliable Actors usługi Service Fabric
Reliable Actors to struktura aplikacji usługi Service Fabric oparta na wzorcu wirtualnego aktora . Interfejs API Reliable Actors udostępnia jednowątkowy model programowania oparty na gwarancjach skalowalności i niezawodności oferowanych przez usługę Service Fabric.
Co to są aktorzy?
Aktor jest izolowaną, niezależną jednostką obliczeniową i stanową z wykonywaniem jednowątkowym. Wzorzec aktora to model obliczeniowy dla systemów współbieżnych lub rozproszonych, w których duża liczba tych aktorów może być wykonywana jednocześnie i niezależnie od siebie. Aktorzy mogą komunikować się ze sobą i mogą tworzyć więcej aktorów.
Kiedy należy używać elementów Reliable Actors
Usługa Service Fabric Reliable Actors to implementacja wzorca projektowego aktora. Podobnie jak w przypadku dowolnego wzorca projektowania oprogramowania, decyzja o tym, czy należy użyć określonego wzorca, jest dokonana na podstawie tego, czy problem projektowy oprogramowania pasuje do wzorca.
Mimo że wzorzec projektowania aktora może być dobrym rozwiązaniem dla wielu problemów i scenariuszy rozproszonych, należy uważnie rozważyć ograniczenia wzorca i implementację struktury. Ogólnie rzecz biorąc, rozważ wzorzec aktora w celu modelowania problemu lub scenariusza, jeśli:
- Obszar problemu obejmuje dużą liczbę (tysiące lub więcej) małych, niezależnych i izolowanych jednostek stanu i logiki.
- Chcesz pracować z obiektami jednowątkowymi, które nie wymagają znaczącej interakcji ze składnikami zewnętrznymi, w tym ze stanem wykonywania zapytań w zestawie aktorów.
- Wystąpienia aktora nie blokują obiektów wywołujących z nieprzewidywalnymi opóźnieniami, wydając operacje we/wy.
Aktorzy w usłudze Service Fabric
W usłudze Service Fabric aktorzy są implementowane w strukturze Reliable Actors: struktura aplikacji oparta na wzorcu opartym na aktorach oparta na usługach Service Fabric Reliable Services. Każda napisana usługa Reliable Actor jest w rzeczywistości partycjonowaną, stanową usługą Reliable Service.
Każdy aktor jest definiowany jako wystąpienie typu aktora, identyczny ze sposobem, w jaki obiekt platformy .NET jest wystąpieniem typu .NET. Na przykład może istnieć typ aktora, który implementuje funkcjonalność kalkulatora i może istnieć wiele podmiotów tego typu, które są dystrybuowane w różnych węzłach w klastrze. Każdy taki aktor jest jednoznacznie identyfikowany przez identyfikator aktora.
Aktor dożywotni
Aktorzy usługi Service Fabric są wirtualni, co oznacza, że ich okres istnienia nie jest powiązany z reprezentacją w pamięci. W związku z tym nie muszą być jawnie tworzone ani niszczone. Środowisko uruchomieniowe Reliable Actors automatycznie aktywuje aktora przy pierwszym otrzymaniu żądania dla tego identyfikatora aktora. Jeśli aktor nie jest używany przez pewien czas, środowisko uruchomieniowe Reliable Actors odśmieca obiekt w pamięci. Będzie ona również utrzymywać wiedzę na temat istnienia aktora, jeśli będzie musiała zostać ponownie aktywowana później. Aby uzyskać więcej informacji, zobacz Cykl życia aktora i odzyskiwanie pamięci.
Ta abstrakcja życia wirtualnego aktora wiąże się z pewnymi zastrzeżeniami w wyniku modelu aktora wirtualnego, a w rzeczywistości implementacja Reliable Actors czasami odbiega od tego modelu.
- Aktor jest automatycznie aktywowany (powodując utworzenie obiektu aktora) przy pierwszym wysłaniu wiadomości do identyfikatora aktora. Po pewnym czasie obiekt aktora jest bezużyteczny. W przyszłości użycie identyfikatora aktora powoduje utworzenie nowego obiektu aktora. Stan aktora przeżywa okres istnienia obiektu, gdy jest przechowywany w menedżerze stanu.
- Wywoływanie dowolnej metody aktora dla identyfikatora aktora aktywuje tego aktora. Z tego powodu typy aktorów mają swój konstruktor nazywany niejawnie przez środowisko uruchomieniowe. W związku z tym kod klienta nie może przekazać parametrów do konstruktora typu aktora, chociaż parametry mogą być przekazywane do konstruktora aktora przez samą usługę. Wynikiem jest to, że aktorzy mogą być konstruowani w stanie częściowo zainicjowanym przez czas wywoływania innych metod, jeśli aktor wymaga parametrów inicjowania od klienta. Nie ma pojedynczego punktu wejścia dla aktywacji aktora od klienta.
- Chociaż element Reliable Actors niejawnie tworzy obiekty aktora; Masz możliwość jawnego usunięcia aktora i jego stanu.
Dystrybucja i tryb failover
Aby zapewnić skalowalność i niezawodność, usługa Service Fabric dystrybuuje aktorów w całym klastrze i automatycznie migruje je z węzłów, które zakończyły się niepowodzeniem do węzłów w dobrej kondycji zgodnie z potrzebami. Jest to abstrakcja partycjonowanej, stanowej niezawodnej usługi. Dystrybucja, skalowalność, niezawodność i automatyczne przełączanie w tryb failover są zapewniane ze względu na fakt, że aktorzy działają w stanowej usłudze Reliable Service o nazwie Usługa aktora.
Aktorzy są dystrybuowani między partycje usługi aktora, a te partycje są dystrybuowane między węzłami w klastrze usługi Service Fabric. Każda partycja usługi zawiera zestaw aktorów. Usługa Service Fabric zarządza dystrybucją i trybem failover partycji usługi.
Na przykład usługa aktora z dziewięcioma partycjami wdrożona w trzech węzłach przy użyciu domyślnego umieszczania partycji aktora będzie w ten sposób dystrybuowana:
Platforma aktorów zarządza schematem partycji i ustawieniami zakresu kluczy. Upraszcza to niektóre opcje, ale również ma pewne kwestie:
- Usługi Reliable Services umożliwiają wybór schematu partycjonowania, zakresu kluczy (w przypadku używania schematu partycjonowania zakresu) i liczby partycji. Funkcja Reliable Actors jest ograniczona do schematu partycjonowania zakresu (jednolity schemat Int64) i wymaga użycia pełnego zakresu kluczy Int64.
- Domyślnie aktorzy są losowo umieszczane w partycjach, co powoduje jednolity rozkład.
- Ponieważ aktorzy są losowo umieszczani, należy się spodziewać, że operacje aktora zawsze będą wymagały komunikacji sieciowej, w tym serializacji i deserializacji danych wywołania metody, ponoszenia opóźnień i narzutu.
- W zaawansowanych scenariuszach można kontrolować umieszczanie partycji aktora przy użyciu identyfikatorów aktorów Int64 mapowanych na określone partycje. Może to jednak spowodować niezrównoważone rozmieszczenie aktorów między partycjami.
Aby uzyskać więcej informacji na temat partycjonowania usług aktora, zobacz partycjonowanie pojęć dotyczących aktorów.
Komunikacja aktora
Interakcje aktora są definiowane w interfejsie udostępnianym przez aktora, który implementuje interfejs, a klient, który pobiera serwer proxy do aktora za pośrednictwem tego samego interfejsu. Ponieważ ten interfejs służy do asynchronicznego wywoływania metod aktora, każda metoda w interfejsie musi być zwracana przez zadanie.
Wywołania metody i ich odpowiedzi ostatecznie powodują żądania sieciowe w klastrze, więc argumenty i typy wyników zwracanych zadań muszą być serializowalne przez platformę. W szczególności muszą być one serializowalne w umowie danych.
Serwer proxy aktora
Interfejs API klienta Reliable Actors zapewnia komunikację między wystąpieniem aktora a klientem aktora. Aby komunikować się z aktorem, klient tworzy obiekt proxy aktora, który implementuje interfejs aktora. Klient wchodzi w interakcję z aktorem, wywołując metody na obiekcie proxy. Serwer proxy aktora może służyć do komunikacji między klientem a aktorem i aktorem.
// Create a randomly distributed actor ID
ActorId actorId = ActorId.CreateRandom();
// This only creates a proxy object, it does not activate an actor or invoke any methods yet.
IMyActor myActor = ActorProxy.Create<IMyActor>(actorId, new Uri("fabric:/MyApp/MyActorService"));
// This will invoke a method on the actor. If an actor with the given ID does not exist, it will be activated by this method call.
await myActor.DoWorkAsync();
// Create actor ID with some name
ActorId actorId = new ActorId("Actor1");
// This only creates a proxy object, it does not activate an actor or invoke any methods yet.
MyActor myActor = ActorProxyBase.create(actorId, new URI("fabric:/MyApp/MyActorService"), MyActor.class);
// This will invoke a method on the actor. If an actor with the given ID does not exist, it will be activated by this method call.
myActor.DoWorkAsync().get();
Należy pamiętać, że dwa elementy informacji używane do tworzenia obiektu proxy aktora są identyfikatorem aktora i nazwą aplikacji. Identyfikator aktora jednoznacznie identyfikuje aktora, a nazwa aplikacji identyfikuje aplikację usługi Service Fabric, w której jest wdrażany aktor.
ActorProxy
Klasa (C#) / ActorProxyBase
(Java) po stronie klienta wykonuje niezbędne rozwiązanie, aby zlokalizować aktora według identyfikatora i otworzyć kanał komunikacji z nim. Ponawia również próbę zlokalizowania aktora w przypadku awarii komunikacji i przejścia w tryb failover. W związku z tym dostarczanie komunikatów ma następujące cechy:
- Dostarczanie komunikatów jest najlepszym rozwiązaniem.
- Aktorzy mogą odbierać zduplikowane komunikaty z tego samego klienta.
Współbieżność
Środowisko uruchomieniowe Reliable Actors udostępnia prosty model dostępu opartego na kolei na potrzeby uzyskiwania dostępu do metod aktora. Oznacza to, że w dowolnym momencie nie więcej niż jeden wątek może być aktywny wewnątrz kodu obiektu aktora. Dostęp oparty na kolei znacznie upraszcza współbieżne systemy, ponieważ nie ma potrzeby mechanizmów synchronizacji na potrzeby dostępu do danych. Oznacza to również, że systemy muszą być zaprojektowane ze szczególnym uwzględnieniem charakteru dostępu jednowątkowego każdego wystąpienia aktora.
- Pojedyncze wystąpienie aktora nie może jednocześnie przetworzyć więcej niż jednego żądania. Wystąpienie aktora może spowodować wąskie gardło przepływności, jeśli oczekuje się, że będzie obsługiwać żądania współbieżne.
- Aktorzy mogą zakleszczać się, jeśli istnieje cykliczne żądanie między dwoma aktorami, podczas gdy żądanie zewnętrzne jest wykonywane do jednego z aktorów jednocześnie. Środowisko uruchomieniowe aktora automatycznie upłynął limit czasu na wywołania aktora i zgłosi wyjątek do rozmówcy, aby przerwać możliwe sytuacje zakleszczenia.
Dostęp oparty na turn-based
Zwrot składa się z kompletnego wykonania metody aktora w odpowiedzi na żądanie od innych aktorów lub klientów albo całkowite wykonanie wywołania zwrotnego czasomierza/przypomnienia . Mimo że te metody i wywołania zwrotne są asynchroniczne, środowisko uruchomieniowe Actors nie przeplata ich. Przed zezwoleniem na nowy obrót musi zostać w pełni zakończony. Innymi słowy, metoda aktora lub czasomierz/wywołanie zwrotne przypomnienia, które jest obecnie wykonywane, musi zostać w pełni zakończone, zanim nowe wywołanie metody lub wywołanie zwrotne jest dozwolone. Uważa się, że metoda lub wywołanie zwrotne zostały zakończone, jeśli wykonanie zostało zwrócone z metody lub wywołania zwrotnego, a zadanie zwrócone przez metodę lub wywołanie zwrotne zostało zakończone. Warto podkreślić, że współbieżność oparta na kolei jest przestrzegana nawet w różnych metodach, czasomierzach i wywołaniach zwrotnych.
Środowisko uruchomieniowe Actors wymusza współbieżność opartą na kolei przez uzyskanie blokady poszczególnych aktorów na początku kolei i zwolnienie blokady na końcu kolei. W związku z tym współbieżność oparta na kolei jest wymuszana na podstawie poszczególnych aktorów, a nie między aktorami. Metody aktora i wywołania zwrotne czasomierza/przypomnienia mogą być wykonywane jednocześnie w imieniu różnych aktorów.
Poniższy przykład ilustruje powyższe pojęcia. Rozważ typ aktora, który implementuje dwie metody asynchroniczne (np . Method1 i Method2), czasomierz i przypomnienie. Na poniższym diagramie przedstawiono przykład osi czasu wykonywania tych metod i wywołań zwrotnych w imieniu dwóch aktorów (ActorId1 i ActorId2), które należą do tego typu aktora.
Ten diagram jest zgodny z tymi konwencjami:
- Każda linia pionowa pokazuje logiczny przepływ wykonywania metody lub wywołania zwrotnego w imieniu określonego aktora.
- Zdarzenia oznaczone na każdej linii pionowej występują w kolejności chronologicznej, a nowsze zdarzenia występują poniżej starszych.
- Różne kolory są używane dla osi czasu odpowiadających różnym aktorom.
- Wyróżnianie służy do wskazywania czasu trwania blokady dla poszczególnych aktorów w imieniu metody lub wywołania zwrotnego.
Należy wziąć pod uwagę kilka ważnych kwestii:
- Podczas gdy metoda1 jest wykonywana w imieniu AktorId2 w odpowiedzi na żądanie klienta xyz789, kolejne żądanie klienta (abc123) pojawia się, które wymaga również wykonania metody Method1 przez ActorId2. Jednak drugie wykonanie metody Method1 nie rozpoczyna się dopiero po zakończeniu wcześniejszego wykonania. Podobnie przypomnienie zarejestrowane przez AktorId2 jest uruchamiane, gdy metoda Method1 jest wykonywana w odpowiedzi na żądanie klienta xyz789. Wywołanie zwrotne przypomnienia jest wykonywane dopiero po zakończeniu obu wykonań metody Method1 . Wszystko to jest spowodowane wymuszaniem współbieżności opartej na kolei dla AktorId2.
- Podobnie współbieżność oparta na kolei jest również wymuszana dla aktoraId1, jak pokazano przez wykonanie metody Method1, Method2 i wywołania zwrotnego czasomierza w imieniu AktorId1 dzieje się w sposób seryjny.
- Wykonanie metody Method1 w imieniu AktorId1 nakłada się na jego wykonanie w imieniu AktorId2. Dzieje się tak, ponieważ współbieżność oparta na kolei jest wymuszana tylko w obrębie aktora, a nie między aktorami.
- W niektórych wykonaniach
Task
metody/wywołania zwrotnego (C#) /CompletableFuture
(Java) zwracanych przez metodę/wywołanie zwrotne kończy się po zwróceniu metody. W niektórych innych operacja asynchroniczna została już zakończona przez czas zwracania metody/wywołania zwrotnego. W obu przypadkach blokada poszczególnych aktorów jest zwalniana tylko po powrocie metody/wywołania zwrotnego i zakończeniu operacji asynchronicznej.
Ponowne wejścia
Środowisko uruchomieniowe Actors domyślnie zezwala na ponowne zalogowanie. Oznacza to, że jeśli metoda aktora aktora A wywołuje metodę w aktorze B, która z kolei wywołuje inną metodę w aktorze A, ta metoda może zostać uruchomiona. Jest to spowodowane tym, że jest częścią tego samego kontekstu logicznego łańcucha wywołań. Wszystkie wywołania czasomierza i przypomnienia zaczynają się od nowego kontekstu wywołania logicznego. Aby uzyskać więcej informacji, zobacz reentrancy Reliable Actors.
Zakres gwarancji współbieżności
Środowisko uruchomieniowe Actors zapewnia te gwarancje współbieżności w sytuacjach, w których kontroluje wywołanie tych metod. Na przykład zapewnia te gwarancje dla wywołań metod, które są wykonywane w odpowiedzi na żądanie klienta, a także dla czasomierza i wywołań zwrotnych przypomnień. Jeśli jednak kod aktora bezpośrednio wywołuje te metody poza mechanizmami dostarczonymi przez środowisko uruchomieniowe aktorów, środowisko uruchomieniowe nie może zapewnić żadnych gwarancji współbieżności. Jeśli na przykład metoda jest wywoływana w kontekście zadania, które nie jest skojarzone z zadaniem zwracanym przez metody aktora, środowisko uruchomieniowe nie może zapewnić gwarancji współbieżności. Jeśli metoda jest wywoływana z wątku tworzonego przez aktora samodzielnie, środowisko uruchomieniowe również nie może zapewnić gwarancji współbieżności. W związku z tym, aby wykonywać operacje w tle, aktorzy powinni używać czasomierzy aktorów i przypomnień aktorów , które szanują współbieżność opartą na kolei.
Następne kroki
Rozpocznij od utworzenia pierwszej usługi Reliable Actors: