Patroon Aggregatie van gateway

Azure Traffic Manager

Een gateway gebruiken om verschillende afzonderlijke aanvragen samen te voegen in één aanvraag. Dit patroon is handig wanneer een client meerdere aanroepen naar verschillende back-endsystemen nodig heeft om een bewerking uit te voeren.

Context en probleem

Voor het uitvoeren van een enkele taak heeft een client wellicht meerdere aanroepen naar verschillende back-endservices nodig. Een toepassing die van veel services afhankelijk is om een taak uit te voeren moet bij elke aanvraag resources verbruiken. Wanneer er een nieuwe functie of service aan de toepassing wordt toegevoegd, zijn extra aanvragen nodig, wat leidt tot hogere resourcevereisten en meer netwerkaanroepen. Deze communicatievereisten tussen een client en een back-end kunnen een negatieve invloed hebben op de prestaties en schaal van de toepassing. Microservice-architecturen hebben ertoe geleid dat dit probleem vaker voorkomt, omdat toepassingen die op veel kleinere services zijn gebaseerd van nature meer aanroepen naar verschillende services genereren.

In het volgende diagram verzendt de client aanvragen naar elke service (1,2,3). Elke service verwerkt de aanvraag en stuurt de reactie terug naar de toepassing (4,5,6). Het op deze manier gebruiken van afzonderlijke aanvragen via een mobiel netwerk met hoge latentie is inefficiënt en kan leiden tot verbroken connectiviteit of onvolledige aanvragen. Hoewel elke aanvraag gelijktijdig kan worden uitgevoerd, moet de toepassing gegevens voor elke aanvraag verzenden, wachten op een reactie en de gegevens verwerken, en dat allemaal op afzonderlijke verbindingen, waardoor de kans op fouten wordt vergroot.

Probleemdiagram voor het patroon Gatewayaggregatie

Oplossing

Gebruik een gateway om de communicatiemogelijkheden tussen de client en de services te verminderen. De gateway ontvangt clientaanvragen, verzendt aanvragen naar de verschillende back-endsystemen, combineert de resultaten en stuurt deze dan terug naar de aanvragende client.

Dit patroon kan het aantal aanvragen van de toepassing naar back-endservices verminderen en de prestaties van toepassingen via netwerken met hoge latentie verbeteren.

In het volgende diagram verzendt de toepassing een aanvraag naar de gateway (1). De aanvraag bevat een pakket aanvullende aanvragen. De gateway scheidt deze van elkaar en verwerkt elke aanvraag door deze naar de relevante service te verzenden (2). Elke service retourneert een antwoord naar de gateway (3). De gateway combineert de antwoorden van elke service en stuurt het antwoord naar de toepassing (4). De toepassing maakt één enkele aanvraag en ontvangt slechts één antwoord van de gateway.

Oplossingsdiagram voor het gatewayaggregatiepatroon

Problemen en overwegingen

  • De gateway mag geen koppeling van services tussen back-endservices inschakelen.
  • De gateway moet zich in de buurt van de back-endservices bevinden om latentie zo veel mogelijk te verminderen.
  • De gatewayservice kan een Single Point of Failure genereren. Zorg ervoor dat de gateway goed is ontworpen om te voldoen aan de beschikbaarheidsvereisten van uw toepassing.
  • De gateway kan een knelpunt genereren. Zorg ervoor dat de gateway voldoende capaciteit heeft om de workload te verwerken en kan worden geschaald met het oog op de door u verwachte groei.
  • Voer belastingtests uit op de gateway zodat er geen trapsgewijze fouten voor services optreden.
  • Implementeer een robuust ontwerp met behulp van technieken zoals bulkheads, uitschakeling van circuits, nieuwe pogingen en time-outs.
  • Als een of meer serviceaanroepen te lang duren, kan het acceptabel zijn om een time-out uit te voeren en een gedeeltelijke set gegevens te retourneren. Bekijk hoe uw toepassing met dit scenario omgaat.
  • Gebruik asynchrone I/O om ervoor te zorgen dat een vertraging bij de back-end niet leidt tot prestatieproblemen in de toepassing.
  • Implementeer gedistribueerde tracering met behulp van correlatie-id's om elke afzonderlijke aanroep te volgen.
  • Controleer aanvraaggegevens en de grootte van reacties.
  • Overweeg het retourneren van gegevens in de cache als failoverstrategie voor het afhandelen van fouten.
  • U zou een verzamelingsservice achter de gateway kunnen implementeren in plaats van aggregatie in te bouwen in de gateway. Aggregatie van aanvragen heeft waarschijnlijk andere resourcevereisten dan andere services in de gateway en is mogelijk van invloed op de routering en offloading van de gateway.

Wanneer dit patroon gebruiken

Gebruik dit patroon wanneer:

  • Een client moet communiceren met meerdere back-endservices om een bewerking uit te voeren.
  • De client kan gebruikmaken van netwerken met aanzienlijke latentie, zoals mobiele netwerken.

Dit patroon is mogelijk niet geschikt in de volgende gevallen:

  • U het aantal aanroepen tussen een client en een enkele service via meerdere bewerkingen wilt reduceren. In dit scenario is het wellicht beter om een batchbewerking aan de service toe te voegen.
  • De client of toepassing bevindt zich in de buurt van de back-endservices en latentie is geen belangrijke factor.

Workloadontwerp

Een architect moet evalueren hoe het gatewayaggregatiepatroon kan worden gebruikt in het ontwerp van hun workload om de doelstellingen en principes te verhelpen die worden behandeld in de pijlers van het Azure Well-Architected Framework. Voorbeeld:

Pijler Hoe dit patroon ondersteuning biedt voor pijlerdoelen
Beslissingen over betrouwbaarheidsontwerp helpen uw workload bestand te worden tegen storingen en ervoor te zorgen dat deze herstelt naar een volledig functionerende status nadat er een fout is opgetreden. Met deze topologie kunt u onder andere tijdelijke foutafhandeling verschuiven van een gedistribueerde implementatie tussen clients naar een gecentraliseerde implementatie.

- RE:07 Tijdelijke fouten
Beslissingen over beveiligingsontwerpen helpen de vertrouwelijkheid, integriteit en beschikbaarheid van de gegevens en systemen van uw workload te waarborgen. Deze topologie vermindert vaak het aantal aanraakpunten dat een client heeft met een systeem, waardoor het openbare oppervlak en de verificatiepunten worden verminderd. De geaggregeerde back-ends kunnen volledig geïsoleerd blijven van clients.

- SE:04 Segmentatie
- SE:08 Hardening
Operational Excellence helpt bij het leveren van workloadkwaliteit via gestandaardiseerde processen en teamcohesie. Met dit patroon kunnen back-endlogica onafhankelijk van clients worden ontwikkeld, zodat u de gekoppelde service-implementaties of zelfs gegevensbronnen kunt wijzigen, zonder dat u clientaanraken hoeft te wijzigen.

- OE:04 Hulpprogramma's en processen
Prestatie-efficiëntie helpt uw workload efficiënt te voldoen aan de vereisten door optimalisaties in schalen, gegevens, code. Dit ontwerp kan minder latentie veroorzaken dan een ontwerp waarin de client meerdere verbindingen tot stand brengt. Caching in aggregatie-implementaties minimaliseert aanroepen naar back-endsystemen.

- PE:03 Services selecteren
- PE:08 Gegevensprestaties

Net als bij elke ontwerpbeslissing moet u rekening houden met eventuele compromissen ten opzichte van de doelstellingen van de andere pijlers die met dit patroon kunnen worden geïntroduceerd.

Opmerking

Het volgende voorbeeld laat zien hoe u een eenvoudige NGINX-service voor gateway-aggregatie kunt maken met behulp van 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"}';
    }
  }
}