Wzorzec agregacji za pomocą bramy

Azure Traffic Manager

Używanie bramy w celu agregowania wielu indywidualnych żądań w pojedynczym żądaniu. Ten wzorzec jest przydatny, gdy klient musi skierować wiele wywołań do różnych systemów zaplecza w celu wykonania operacji.

Kontekst i problem

Aby wykonać jedno zadanie, może być konieczne skierowanie wielu wywołań do różnych usług zaplecza. Aplikacja, która korzysta z wielu usług w celu wykonania zadania, musi używać zasobów przy każdym żądaniu. Dodanie nowych funkcji lub usług do aplikacji powoduje, że rośnie liczba potrzebnych żądań, co dodatkowo zwiększa wymagania dotyczące zasobów i liczbę wywołań sieci. Duża liczba operacji między klientem a zapleczem może niekorzystnie wpłynąć na wydajności i skalę aplikacji. Architektury oparte na mikrousługach upowszechniły ten problem, ponieważ aplikacje utworzone wokół wielu mniejszych usług w naturalny sposób wymagają większej liczby wywołań między usługami.

Na poniższym diagramie klient wysyła żądania do poszczególnych usług (1, 2, 3). Każda usługa przetwarza żądanie i wysyła odpowiedź z powrotem do aplikacji (4, 5, 6). W sieci komórkowej, którą zwykle wyróżnia duże opóźnienie, takie wysyłanie poszczególnych żądań jest nieefektywne i może spowodować przerwanie łączności lub pojawienie się niekompletnych żądań. Chociaż transmisja poszczególnych żądań może odbywać się równolegle, aplikacja musi je wysłać, poczekać, a następnie przetworzyć dane za pośrednictwem osobnych połączeń, co zwiększa ryzyko wystąpienia awarii.

Diagram problemu dla wzorca agregacji bramy

Rozwiązanie

Brama umożliwia ograniczenie liczby operacji między klientem i usługami. Brama odbiera żądania klienta, rozsyła je do różnych systemów zaplecza, a następnie agreguje wyniki i wysyła je z powrotem do klienta.

Ten wzorzec może zmniejszyć liczbę żądań wysyłanych przez aplikację do usług zaplecza, zwiększając wydajność aplikacji w sieciach z dużym opóźnieniem.

Na poniższym diagramie aplikacja wysyła żądanie do bramy (1). Żądanie to zawiera pakiet dodatkowych żądań. Brama je rozkłada i przetwarza, wysyłając poszczególne żądania do odpowiednich usług (2). Każda usługa zwraca odpowiedź do bramy (3). Brama łączy odpowiedzi od poszczególnych usług i wysyła zagregowaną odpowiedź do aplikacji (4). Aplikacja wysyła jedno żądanie i odbiera tylko jedną odpowiedź od bramy.

Diagram rozwiązania dla wzorca agregacji bramy

Problemy i kwestie do rozważenia

  • Brama nie powinna wprowadzać sprzężenia między usługami zaplecza.
  • Brama powinna znajdować się w pobliżu usług zaplecza w celu maksymalnego zmniejszenia opóźnień.
  • Usługa bramy może stanowić pojedynczy punkt awarii. Brama musi zostać prawidłowo zaprojektowana pod kątem wymagań dotyczących dostępności aplikacji.
  • Brama może stanowić wąskie gardło. Upewnij się, że brama ma odpowiednią wydajność, zapewniającą obsługę obciążenia, i że można ją skalować w odpowiedzi na rosnące potrzeby.
  • Wykonaj testowanie obciążenia bramy, aby mieć pewność, że nie występują kaskadowe awarie usług.
  • Zaimplementuj odporny projekt przy użyciu technik, takich jak grodzie, wyłączniki, ponawianie i limity czasu.
  • Jeśli co najmniej jedno wywołanie usługi trwa zbyt długo, może być dopuszczalne przekroczenie limitu czasu i zwrócenie częściowego zestawu danych. Zastanów się, jak aplikacja poradzi sobie w tym scenariuszu.
  • Używaj asynchronicznych operacji we/wy, aby zagwarantować, że opóźnienie na zapleczu nie spowoduje problemów z wydajnością aplikacji.
  • W celu śledzenia poszczególnych wywołań zaimplementuj rozproszone śledzenie z użyciem identyfikatorów korelacji.
  • Monitoruj metryki żądań i rozmiary odpowiedzi.
  • W ramach strategii trybu failover służącej do obsługi błędów zastanów się nad zwracaniem buforowanych danych.
  • Zamiast wdrażania agregacji w bramie, umieść usługę agregacji za bramą. Agregacja żądań prawdopodobnie będzie mieć inne wymagania dotyczące zasobów niż pozostałe usługi w bramie. Agregacja może mieć wpływ na funkcje routingu i odciążania bramy.

Kiedy używać tego wzorca

Użyj tego wzorca, gdy:

  • W celu wykonania operacji klient musi komunikować się z wieloma usługami zaplecza.
  • Klient może używać sieci charakteryzujących się znacznym opóźnieniem, takich jak sieć komórkowa.

Ten wzorzec może być nieodpowiedni w następujących przypadkach:

  • Chcesz zmniejszyć liczbę wywołań między klientem a pojedynczą usługą w wielu operacjach. W tym scenariuszu lepszym rozwiązaniem może okazać się dodanie operacji zbiorczej do usługi.
  • Klient lub aplikacja znajduje się w pobliżu usług zaplecza, a opóźnienie nie jest istotnym czynnikiem.

Projekt obciążenia

Architekt powinien ocenić, w jaki sposób wzorzec agregacji bramy może być używany w projekcie obciążenia, aby sprostać celom i zasadom opisanym w filarach platformy Azure Well-Architected Framework. Na przykład:

Filar Jak ten wzorzec obsługuje cele filaru
Decyzje projektowe dotyczące niezawodności pomagają obciążeniu stać się odporne na awarię i zapewnić, że zostanie przywrócony do w pełni funkcjonalnego stanu po wystąpieniu awarii. Ta topologia umożliwia między innymi przesunięcie obsługi błędów przejściowych z implementacji rozproszonej między klientami do scentralizowanej implementacji.

- RE:07 Błędy przejściowe
Decyzje dotyczące projektowania zabezpieczeń pomagają zapewnić poufność, integralność i dostępność danych i systemów obciążenia. Ta topologia często zmniejsza liczbę punktów dotykowych, które klient ma w systemie, co zmniejsza obszar powierzchni publicznej i punkty uwierzytelniania. Zagregowane zaplecza mogą pozostać w pełni odizolowane od sieci od klientów.

- Segmentacja SE:04
- SE:08 Wzmacnianie zabezpieczeń
Doskonałość operacyjna pomaga zapewnić jakość obciążeń dzięki ustandaryzowanym procesom i spójności zespołu. Ten wzorzec umożliwia ewolucję logiki zaplecza niezależnie od klientów, co umożliwia zmianę implementacji usługi łańcuchowej, a nawet źródeł danych bez konieczności zmieniania punktów dotykowych klienta.

- OE:04 Narzędzia i procesy
Wydajność pomaga wydajnie sprostać zapotrzebowaniu dzięki optymalizacjom skalowania, danych, kodu. Ten projekt może spowodować mniejsze opóźnienie niż projekt, w którym klient nawiązuje wiele połączeń. Buforowanie w implementacjach agregacji minimalizuje wywołania systemów zaplecza.

- PE:03 Wybieranie usług
- PE:08 Wydajność danych

Podobnie jak w przypadku każdej decyzji projektowej, należy rozważyć wszelkie kompromisy w stosunku do celów innych filarów, które mogą zostać wprowadzone przy użyciu tego wzorca.

Przykład

Poniższy przykład przedstawia tworzenie prostej usługi NGINX służącej do agregacji bramy przy użyciu skryptu Lua.

worker_processes  4;

events {
  worker_connections 1024;
}

http {
  server {
    listen 80;

    location = /batch {
      content_by_lua '
        ngx.req.read_body()

        -- read json body content
        local cjson = require "cjson"
        local batch = cjson.decode(ngx.req.get_body_data())["batch"]

        -- create capture_multi table
        local requests = {}
        for i, item in ipairs(batch) do
          table.insert(requests, {item.relative_url, { method = ngx.HTTP_GET}})
        end

        -- execute batch requests in parallel
        local results = {}
        local resps = { ngx.location.capture_multi(requests) }
        for i, res in ipairs(resps) do
          table.insert(results, {status = res.status, body = cjson.decode(res.body), header = res.header})
        end

        ngx.say(cjson.encode({results = results}))
      ';
    }

    location = /service1 {
      default_type application/json;
      echo '{"attr1":"val1"}';
    }

    location = /service2 {
      default_type application/json;
      echo '{"attr2":"val2"}';
    }
  }
}