Udostępnij za pośrednictwem


Wzorce zadań replikacji komunikatów

Omówienie federacji i omówienie funkcji replikatora wyjaśniają uzasadnienie i podstawowe elementy zadań replikacji. Zaleca się zapoznanie się z nimi przed kontynuowaniem pracy z tym artykułem.

W tym artykule szczegółowo przedstawiono wskazówki dotyczące implementacji kilku wzorców wyróżnionych w sekcji przeglądu.

Replikacja

Wzorzec replikacji kopiuje komunikaty z jednej kolejki lub tematu do następnej albo z kolejki lub tematu do innego miejsca docelowego, takiego jak centrum zdarzeń. Komunikaty są przekazywane bez wprowadzania żadnych modyfikacji ładunku komunikatu.

Implementacja tego wzorca jest objęta replikacją komunikatów do i z przykładu usługi Azure Service Bus .

Sekwencje i zachowywanie kolejności

Model replikacji nie ma na celu zachowania bezwzględnej kolejności komunikatów kolejki źródłowej lub tematu w docelowej kolejce lub temacie, ale koncentruje się zawsze, gdy jest to wymagane, w celu zachowania względnej kolejności komunikatów, w których aplikacja tego wymaga. Aplikacja włącza tę funkcję, włączając obsługę sesji dla jednostki źródłowej i grupowanie powiązanych komunikatów z tym samym kluczem sesji.

Wstępnie skompilowane funkcje replikacji obsługujące sesję zapewniają, że sekwencje komunikatów o tym samym identyfikatorze sesji pobranym z jednostki źródłowej są przesyłane do kolejki docelowej lub tematu jako partii w oryginalnej sekwencji i z tym samym identyfikatorem sesji.

Metadane przypisane przez usługę

Metadane przypisane przez usługę komunikatu uzyskanego z kolejki źródłowej lub tematu, oryginalny czas kolejkowania i numer sekwencji, są zastępowane przez nowe wartości przypisane przez usługę w kolejce docelowej lub temacie, ale z domyślnymi zadaniami replikacji podanymi w naszych przykładach oryginalne wartości są zachowywane we właściwościach użytkownika: repl-enqueue-time (ISO8601 ciąg) i repl-sequence.

Te właściwości są typu ciąg i zawierają ciągyfikowaną wartość odpowiednich oryginalnych właściwości. Jeśli komunikat jest przekazywany wiele razy, metadane przypisane przez usługę natychmiastowego źródła są dołączane do już istniejących właściwości z wartościami rozdzielonymi średnikami.

Tryb failover

Jeśli używasz replikacji do celów odzyskiwania po awarii, aby chronić przed regionalnymi komunikatami dostępności w usłudze Service Bus lub przed przerwami w działaniu sieci, każdy taki scenariusz awarii będzie wymagał przejścia w tryb failover z jednej kolejki lub tematu do następnej, informując producentów i/lub użytkowników o użyciu pomocniczego punktu końcowego.

W przypadku wszystkich scenariuszy trybu failover zakłada się, że wymagane elementy przestrzeni nazw są strukturalnie identyczne, co oznacza, że kolejki i tematy są identycznie nazwane i że reguły sygnatur dostępu współdzielonego i/lub reguły kontroli dostępu opartej na rolach są konfigurowane w taki sam sposób. Możesz utworzyć (i zaktualizować) pomocniczą przestrzeń nazw, postępując zgodnie ze wskazówkami dotyczącymi przenoszenia przestrzeni nazw i pomijania kroku oczyszczania.

Aby zmusić producentów i konsumentów do przełączenia, należy udostępnić informacje o przestrzeni nazw, która ma być używana do wyszukiwania w lokalizacji, która jest łatwa do uzyskania i zaktualizowania. Jeśli producenci lub konsumenci napotykają częste lub trwałe błędy, powinni skonsultować się z tym miejscem i dostosować konfigurację. Istnieje wiele sposobów udostępniania tej konfiguracji, ale wskazujemy dwa w następujących kwestiach: DNS i udziały plików.

Konfiguracja trybu failover oparta na systemie DNS

Jednym z kandydatów jest utrzymywanie informacji w rekordach SRV DNS w systemie DNS, który kontrolujesz i wskazuje odpowiednie punkty końcowe kolejki lub tematu. Należy pamiętać, że usługa Message Hubs nie zezwala na bezpośrednie aliasy punktów końcowych z rekordami CNAME, co oznacza, że system DNS będzie używany jako odporny mechanizm wyszukiwania dla adresów końcowych, a nie do bezpośredniego rozpoznawania informacji o adresach IP.

Załóżmy, że jesteś właścicielem domeny example.com i dla aplikacji strefą test.example.com. W przypadku dwóch alternatywnych usług Service Bus utworzysz teraz dwie kolejne strefy zagnieżdżone i rekord SRV w każdym z nich.

Rekordy SRV są zgodne z wspólną konwencją, poprzedzone i przechowują _azure_servicebus._amqp dwa rekordy punktu końcowego: jeden dla protokołu AMQP-over-TLS na porcie 5671 i jeden dla protokołu AMQP-over-WebSockets na porcie 443, zarówno wskazując punkt końcowy usługi Service Bus przestrzeni nazw odpowiadającej strefie.

Strefa Rekord SRV
sb1.test.example.com _azure_servicebus._amqp.sb1.test.example.com
1 1 5671 sb1-test-example-com.servicebus.windows.net
2 2 443 sb1-test-example-com.servicebus.windows.net
sb2.test.example.com _azure_servicebus._amqp.sb1.test.example.com
1 1 5671 sb2-test-example-com.servicebus.windows.net
2 2 443 sb2-test-example-com.servicebus.windows.net

W strefie aplikacji utworzysz wpis CNAME wskazujący strefę podrzędną odpowiadającą podstawowej kolejce lub tematowi:

Rekord CNAME Alias
servicebus.test.example.com sb1.test.example.com

Korzystając z klienta DNS, który umożliwia jawne wykonywanie zapytań dotyczących rekordów CNAME i SRV (wbudowanych klientów języka Java i platformy .NET zezwala tylko na proste rozpoznawanie nazw na adresy IP), można następnie rozpoznać żądany punkt końcowy. Na przykład w przypadku DnsClient.NET funkcja wyszukiwania to:

static string GetServiceBusName(string aliasName)
{
    const string SrvRecordPrefix = "_azure_servicebus._amqp.";
    LookupClient lookup = new LookupClient();

    return (from CNameRecord alias in (lookup.Query(aliasName, QueryType.CNAME).Answers)
            from SrvRecord srv in lookup.Query(SrvRecordPrefix + alias.CanonicalName, QueryType.SRV).Answers
            where srv.Port == 5671
            select srv.Target).FirstOrDefault()?.Value.TrimEnd('.');
}

Funkcja zwraca docelową nazwę hosta zarejestrowaną dla portu 5671 strefy, która jest obecnie aliasem cNAME, jak pokazano powyżej.

Przejście w tryb failover wymaga edytowania rekordu CNAME i wskazywania go w strefie alternatywnej.

Zaletą korzystania z usługi DNS, a w szczególności usługi Azure DNS, jest to, że informacje usługi Azure DNS są globalnie replikowane i dlatego odporne na awarie w jednym regionie.

Ta procedura jest podobna do sposobu działania geo-odzyskiwania po awarii usługi Service Bus, ale w pełni pod własną kontrolą, a także działa w scenariuszach aktywnych/aktywnych.

Konfiguracja trybu failover opartego na udziale plików

Najprostszą alternatywą dla używania systemu DNS do udostępniania informacji o punkcie końcowym jest umieszczenie nazwy podstawowego punktu końcowego w pliku zwykłego tekstu i udostępnienie pliku z infrastruktury, która jest niezawodna w przypadku awarii i nadal zezwala na aktualizacje.

Jeśli już uruchomiono infrastrukturę witryn sieci Web o wysokiej dostępności z globalną dostępnością i replikacją zawartości, dodaj tam taki plik i opublikuj go ponownie, jeśli jest potrzebny przełącznik.

Scal

Wzorzec scalania zawiera co najmniej jedno zadanie replikacji wskazujące jeden element docelowy, prawdopodobnie współbieżnie z regularnymi producentami, którzy również wysyłają komunikaty do tego samego celu.

Odmiany tego wzorca to:

  • Co najmniej dwie funkcje replikacji jednocześnie uzyskują komunikaty z oddzielnych źródeł i wysyłają je do tego samego obiektu docelowego.
  • Jeszcze jedna funkcja replikacji uzyskująca komunikaty ze źródła, podczas gdy element docelowy jest również używany bezpośrednio przez producentów.
  • Poprzedni wzorzec, ale komunikaty dublowane między co najmniej dwoma tematami, co powoduje, że te tematy zawierają te same komunikaty, niezależnie od tego, gdzie są generowane komunikaty.

Pierwsze dwie odmiany wzorca są proste i nie różnią się od zwykłych zadań replikacji.

Ostatni scenariusz wymaga ponownego zreplikowania już replikowanych komunikatów. Technika jest pokazana i wyjaśniona w przykładzie aktywnym/aktywnym.

Redaktor

Wzorzec edytora opiera się na wzorcu replikacji , ale komunikaty są modyfikowane przed ich przekazaniem. Przykłady takich modyfikacji to:

  • Transkodowanie — jeśli zawartość komunikatu (określana również jako "treść" lub "ładunek") dociera ze źródła zakodowanego przy użyciu formatu Apache Avro lub zastrzeżonego formatu serializacji, ale oczekiwanie systemu będącego właścicielem obiektu docelowego jest dla zawartości zakodowanej w formacie JSON, zadanie replikacji transkodowania najpierw zdeserializuje ładunek z apache Avro do grafu obiektu w pamięci, a następnie serializuje ten graf w formacie JSON format komunikatu, który jest przekazywany. Transkodowanie obejmuje również zadania kompresji i dekompresacji zawartości.
  • Przekształcanie — komunikaty zawierające dane ustrukturyzowane mogą wymagać zmiany tych danych w celu łatwiejszego użycia przez odbiorców podrzędnych. Może to obejmować pracę, taką jak spłaszczanie zagnieżdżonych struktur, oczyszczanie nadmiarowych elementów danych lub zmiana ładunku w taki sposób, aby dokładnie pasował do danego schematu.
  • Przetwarzanie wsadowe — komunikaty mogą być odbierane w partiach (wiele komunikatów w jednym transferze) ze źródła, ale muszą być przekazywane pojedynczo do miejsca docelowego lub odwrotnie. W związku z tym zadanie może przekazywać wiele komunikatów na podstawie jednego transferu komunikatów wejściowych lub agregować zestaw komunikatów, które następnie są przesyłane razem.
  • Walidacja — dane komunikatów ze źródeł zewnętrznych często muszą być sprawdzane pod kątem zgodności z zestawem reguł przed ich przekazaniem. Reguły mogą być wyrażane przy użyciu schematów lub kodu. komunikaty, które nie są zgodne, mogą zostać porzucone, z problemem zanotowanym w dziennikach lub mogą być przekazywane do specjalnego docelowego miejsca docelowego, aby obsłużyć je dalej.
  • Wzbogacanie — dane komunikatów pochodzące z niektórych źródeł mogą wymagać wzbogacania z dalszym kontekstem, aby można je było używać w systemach docelowych. Może to obejmować wyszukanie danych referencyjnych i osadzanie tych danych za pomocą komunikatu lub dodanie informacji o źródle, które jest znane zadaniu replikacji, ale nie zawarte w komunikatach.
  • Filtrowanie — niektóre komunikaty przychodzące ze źródła mogą być wstrzymane z obiektu docelowego na podstawie niektórych reguł. Filtr testuje komunikat względem reguły i odrzuca komunikat, jeśli komunikat nie jest zgodny z regułą. Filtrowanie zduplikowanych komunikatów przez obserwowanie określonych kryteriów i usuwanie kolejnych komunikatów z tymi samymi wartościami jest formą filtrowania.
  • Routing i partycjonowanie — niektóre zadania replikacji mogą zezwalać na co najmniej dwa alternatywne obiekty docelowe i definiować reguły, dla których cel replikacji jest wybierany dla dowolnego konkretnego komunikatu na podstawie metadanych lub zawartości komunikatu. Specjalną formą routingu jest partycjonowanie, gdzie zadanie jawnie przypisuje partycje w jednym obiekcie docelowym replikacji na podstawie reguł.
  • Kryptografia — zadanie replikacji może wymagać odszyfrowywania zawartości pochodzącej ze źródła i/lub szyfrowania zawartości przekazanej do miejsca docelowego i/lub może być konieczne zweryfikowanie integralności zawartości i metadanych względem podpisu przenoszonego w wiadomości lub dołączenia takiego podpisu.
  • Zaświadczanie — zadanie replikacji może dołączać metadane, potencjalnie chronione przez podpis cyfrowy, do komunikatu, który potwierdza, że wiadomość została odebrana za pośrednictwem określonego kanału lub w określonym czasie.
  • Łańcuch — zadanie replikacji może stosować podpisy do sekwencji komunikatów, tak aby integralność sekwencji jest chroniona i można wykryć brakujące komunikaty.

Wszystkie te wzorce można zaimplementować przy użyciu usługi Azure Functions, używając wyzwalacza usługi Message Hubs do uzyskiwania komunikatów oraz powiązania wyjściowego kolejki lub tematu na potrzeby ich dostarczania.

Routing

Wzorzec routingu opiera się na wzorcu replikacji, ale zamiast jednego źródła i jednego miejsca docelowego zadanie replikacji ma wiele obiektów docelowych, zilustrowanych tutaj w języku C#:

[FunctionName("SBRouter")]
public static async Task Run(
    [ServiceBusTrigger("source", Connection = "serviceBusConnectionAppSetting")] ServiceBusReceivedMessage[] messages,
    [ServiceBusOutput("dest1", Connection = "serviceBusConnectionAppSetting")] IAsyncCollector<dynamic> output1,
    [ServiceBusOutput("dest2", Connection = "serviceBusConnectionAppSetting")] IAsyncCollector<dynamic> output2,
    ILogger log)
{
    foreach (Message messageData in messages)
    {
        // send to output1 or output2 based on criteria 
    }
}

Funkcja routingu będzie uwzględniać metadane komunikatów i/lub ładunek komunikatu, a następnie wybrać jedno z dostępnych miejsc docelowych do wysłania.

Następne kroki