Muster „Gatewayaggregation“Gateway Aggregation pattern

Aggregieren Sie mithilfe eines Gateways mehrere einzelne Anforderungen in einer einzigen Anforderung.Use a gateway to aggregate multiple individual requests into a single request. Dieses Muster ist hilfreich, wenn ein Client zur Durchführung eines Vorgangs mehrere Aufrufe an verschiedene Back-End-Systeme tätigen muss.This pattern is useful when a client must make multiple calls to different backend systems to perform an operation.

Kontext und ProblemContext and problem

Um eine einzelne Aufgabe auszuführen, muss ein Client möglicherweise mehrere Aufrufe von verschiedenen Back-End-Diensten durchführen.To perform a single task, a client may have to make multiple calls to various backend services. Eine Anwendung, die zur Ausführung einer Aufgabe auf viele Dienste angewiesen ist, muss für jede Anforderung Ressourcen aufwenden.An application that relies on many services to perform a task must expend resources on each request. Wenn der Anwendung neue Features oder Dienste hinzugefügt werden, sind zusätzliche Anforderungen erforderlich, durch die sich der Ressourcenbedarf und die Anzahl der Netzwerkaufrufe weiter erhöhen.When any new feature or service is added to the application, additional requests are needed, further increasing resource requirements and network calls. Eine derart umfangreiche Interaktion (Chattiness) zwischen einer Client- und einer Back-End-Anwendung können Leistung und Skalierung der Anwendung beeinträchtigen.This chattiness between a client and a backend can adversely impact the performance and scale of the application. Durch Microservicearchitekturen ist dieses Problem immer verbreiteter geworden, da Anwendungen, die um viele kleinere Dienste herum erstellt werden, in der Regel eine größere Anzahl von dienstübergreifenden Aufrufen aufweisen.Microservice architectures have made this problem more common, as applications built around many smaller services naturally have a higher amount of cross-service calls.

Im folgenden Diagramm sendet der Client Anforderungen an jeden Dienst (1, 2, 3).In the following diagram, the client sends requests to each service (1,2,3). Jeder Dienst verarbeitet die Anforderung und sendet die Antwort an die Anwendung zurück (4, 5, 6).Each service processes the request and sends the response back to the application (4,5,6). Bei einem Mobilfunknetz mit üblicherweise hohen Latenzen ist ein derartiger Einsatz einzelner Anforderungen ineffizient und kann Konnektivitätsabbrüche oder unvollständige Anforderungen verursachen.Over a cellular network with typically high latency, using individual requests in this manner is inefficient and could result in broken connectivity or incomplete requests. Die einzelnen Anforderungen können zwar parallel ausgeführt werden, allerdings muss die Anwendung für jede Anforderung Daten senden und verarbeiten bzw. auf diese warten. Da all diese Vorgänge über separate Verbindungen erfolgen, besteht hierbei eine höhere Wahrscheinlichkeit eines Ausfalls.While each request may be done in parallel, the application must send, wait, and process data for each request, all on separate connections, increasing the chance of failure.

Problemdiagramm für das Muster „Gatewayaggregation“

LösungSolution

Verwenden Sie ein Gateway, um die umfangreiche Interaktion zwischen dem Client und den Diensten (Chattiness) zu reduzieren.Use a gateway to reduce chattiness between the client and the services. Das Gateway empfängt Clientanforderungen, versendet Anforderungen an die verschiedenen Back-End-Systeme, aggregiert die Ergebnisse und sendet sie wieder an den anfordernden Client zurück.The gateway receives client requests, dispatches requests to the various backend systems, and then aggregates the results and sends them back to the requesting client.

Dieses Muster kann die Anzahl der Anforderungen, die die Anwendung an Back-End-Dienste sendet, reduzieren und die Anwendungsleistung für Netzwerke mit hohen Latenzen verbessern.This pattern can reduce the number of requests that the application makes to backend services, and improve application performance over high-latency networks.

Im folgenden Diagramm sendet die Anwendung eine Anforderung an das Gateway (1).In the following diagram, the application sends a request to the gateway (1). Die Anforderung enthält ein Paket mit zusätzlichen Anforderungen.The request contains a package of additional requests. Das Gateway zerlegt diese und verarbeitet jede Anforderung, indem es diese an den entsprechenden Dienst (2) sendet.The gateway decomposes these and processes each request by sending it to the relevant service (2). Jeder Dienst gibt eine Antwort an das Gateway zurück (3).Each service returns a response to the gateway (3). Das Gateway fasst die Antworten der einzelnen Dienste zusammen und sendet die Antwort an die Anwendung (4).The gateway combines the responses from each service and sends the response to the application (4). Die Anwendung erstellt eine einzige Anforderung und erhält nur eine einzige Antwort vom Gateway.The application makes a single request and receives only a single response from the gateway.

Lösungsdiagramm für das Muster „Gatewayaggregation“

Probleme und ÜberlegungenIssues and considerations

  • Das Gateway sollte keine Kopplung zwischen Diensten für die Back-End-Dienste vornehmen.The gateway should not introduce service coupling across the backend services.
  • Das Gateway sollte sich in der Nähe der Back-End-Dienste befinden, um die Latenz so gering wie möglich zu halten.The gateway should be located near the backend services to reduce latency as much as possible.
  • Der Gatewaydienst kann ein Single Point of Failure darstellen.The gateway service may introduce a single point of failure. Stellen Sie sicher, dass das Gateway die Verfügbarkeitsanforderungen Ihrer Anwendung erfüllt.Ensure the gateway is properly designed to meet your application's availability requirements.
  • Das Gateway kann einen Engpass darstellen.The gateway may introduce a bottleneck. Stellen Sie sicher, dass das Gateway über die entsprechende Leistung zur Verarbeitung der Last verfügt und skaliert werden kann, um dem erwarteten Anstieg nachzukommen.Ensure the gateway has adequate performance to handle load and can be scaled to meet your anticipated growth.
  • Führen Sie einen Auslastungstest für das Gateway durch, um sicherzustellen, dass keine kaskadierenden Ausfälle bei den Diensten auftreten.Perform load testing against the gateway to ensure you don't introduce cascading failures for services.
  • Implementieren Sie einen stabilen Entwurf unter Verwendung von Verfahren wie Bulkheads, Sicherung, Wiederholung und Timeouts.Implement a resilient design, using techniques such as bulkheads, circuit breaking, retry, and timeouts.
  • Wenn Dienstaufrufe zu lange dauern, kann es helfen, ein Timeout durchzuführen und einen Teil des Datasets zurückzugeben.If one or more service calls takes too long, it may be acceptable to timeout and return a partial set of data. Berücksichtigen Sie, wie sich Ihre Anwendung in diesem Szenario verhält.Consider how your application will handle this scenario.
  • Verwenden Sie asynchrone E/A-Vorgänge, um sicherzustellen, dass eine Verzögerung am Back-End keine Leistungsprobleme in der Anwendung verursacht.Use asynchronous I/O to ensure that a delay at the backend doesn't cause performance issues in the application.
  • Implementieren Sie mithilfe von Korrelations-IDs verteilte Ablaufverfolgungen, um jeden einzelnen Aufruf nachzuverfolgen.Implement distributed tracing using correlation IDs to track each individual call.
  • Überwachen Sie Anforderungsmetriken und Antwortgrößen.Monitor request metrics and response sizes.
  • Betrachten Sie die Rückgabe von zwischengespeicherten Daten als Failoverstrategie, um Ausfälle zu behandeln.Consider returning cached data as a failover strategy to handle failures.
  • Statt eine Aggregation in das Gateway zu integrieren, sollten Sie eventuell einen Aggregationsdienst hinter dem Gateway platzieren.Instead of building aggregation into the gateway, consider placing an aggregation service behind the gateway. Für die Aggregation von Anforderungen gelten wahrscheinlich andere Ressourcenanforderungen als für andere Dienste im Gateway, was sich auf die Routing- und Abladungsfunktionalität des Gateways auswirken kann.Request aggregation will likely have different resource requirements than other services in the gateway and may impact the gateway's routing and offloading functionality.

Verwendung dieses MustersWhen to use this pattern

Verwenden Sie dieses Muster in folgenden Fällen:Use this pattern when:

  • Ein Client muss mit mehreren Back-End-Diensten kommunizieren, um einen Vorgang durchführen zu können.A client needs to communicate with multiple backend services to perform an operation.
  • Der Client kann Netzwerke mit deutlich hoher Latenz verwenden (z.B. Mobilfunknetze).The client may use networks with significant latency, such as cellular networks.

Dieses Muster ist in folgenden Fällen möglicherweise nicht geeignet:This pattern may not be suitable when:

  • Sie möchten die Anzahl der Aufrufe zwischen einem Client und einem einzelnen Dienst für mehrere Vorgänge reduzieren.You want to reduce the number of calls between a client and a single service across multiple operations. In diesem Szenario kann es besser sein, dem Dienst einen Batchvorgang hinzuzufügen.In that scenario, it may be better to add a batch operation to the service.
  • Der Client oder die Anwendung befindet sich in der Nähe der Back-End-Dienste, und Latenzen spielen keine wesentliche Rolle.The client or application is located near the backend services and latency is not a significant factor.

BeispielExample

Das folgende Beispiel zeigt, wie mit Lua ein einfacher NGINX-Dienst für die Gatewayaggregation erstellt wird.The following example illustrates how to create a simple a gateway aggregation NGINX service using 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"}';
    }
  }
}