API Gateway-mönstret jämfört med direct client-to-microservice-kommunikationen

Dricks

Det här innehållet är ett utdrag från eBook, .NET Microservices Architecture for Containerized .NET Applications, tillgängligt på .NET Docs eller som en kostnadsfri nedladdningsbar PDF som kan läsas offline.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

I en mikrotjänstarkitektur exponerar varje mikrotjänst en uppsättning (vanligtvis) detaljerade slutpunkter. Det här faktumet kan påverka kommunikationen mellan klienter och mikrotjänster, enligt beskrivningen i det här avsnittet.

Direkt kommunikation mellan klienter och mikrotjänster

En möjlig metod är att använda en direkt kommunikationsarkitektur från klient till mikrotjänst. I den här metoden kan en klientapp göra begäranden direkt till några av mikrotjänsterna, enligt bild 4–12.

Diagram showing client-to-microservice communication architecture.

Bild 4-12. Använda en direkt kommunikationsarkitektur från klient till mikrotjänst

I den här metoden har varje mikrotjänst en offentlig slutpunkt, ibland med en annan TCP-port för varje mikrotjänst. Ett exempel på en URL för en viss tjänst kan vara följande URL i Azure:

http://eshoponcontainers.westus.cloudapp.azure.com:88/

I en produktionsmiljö baserad på ett kluster mappas url:en till lastbalanseraren som används i klustret, vilket i sin tur distribuerar begäranden mellan mikrotjänsterna. I produktionsmiljöer kan du ha en programleveranskontrollant (ADC) som Azure Application Gateway mellan dina mikrotjänster och Internet. Det här lagret fungerar som en transparent nivå som inte bara utför belastningsutjämning, utan skyddar dina tjänster genom att erbjuda SSL-avslutning. Den här metoden förbättrar belastningen på dina värdar genom att avlasta CPU-intensiv SSL-avslutning och andra routningsuppgifter till Azure Application Gateway. I vilket fall som helst är en lastbalanserare och ADC transparenta ur ett logiskt programarkitekturperspektiv.

En direkt kommunikationsarkitektur för klient-till-mikrotjänster kan vara tillräckligt bra för ett litet mikrotjänstbaserat program, särskilt om klientappen är ett webbprogram på serversidan som en ASP.NET MVC-app. Men när du skapar stora och komplexa mikrotjänstbaserade program (till exempel när du hanterar dussintals mikrotjänsttyper), och särskilt när klientapparna är fjärranslutna mobilappar eller SPA-webbprogram, har den metoden några problem.

Tänk på följande frågor när du utvecklar ett stort program baserat på mikrotjänster:

  • Hur kan klientappar minimera antalet begäranden till serverdelen och minska pratsam kommunikation till flera mikrotjänster?

Om du interagerar med flera mikrotjänster för att skapa en enda gränssnittsskärm ökar antalet tur- och returresor via Internet. Den här metoden ökar svarstiden och komplexiteten på användargränssnittssidan. Helst bör svar aggregeras effektivt på serversidan. Den här metoden minskar svarstiden eftersom flera datastycken kommer tillbaka parallellt och vissa användargränssnitt kan visa data så snart de är klara.

  • Hur kan du hantera övergripande problem som auktorisering, datatransformeringar och dynamisk sändning av begäranden?

Att implementera säkerhets- och övergripande problem som säkerhet och auktorisering för varje mikrotjänst kan kräva betydande utvecklingsarbete. En möjlig metod är att ha dessa tjänster i Docker-värden eller det interna klustret för att begränsa direkt åtkomst till dem utifrån och implementera dessa övergripande problem på en central plats, till exempel en API Gateway.

  • Hur kan klientappar kommunicera med tjänster som använder icke-Internetvänliga protokoll?

Protokoll som används på serversidan (till exempel AMQP eller binära protokoll) stöds inte i klientappar. Begäranden måste därför utföras via protokoll som HTTP/HTTPS och översättas till de andra protokollen efteråt. En man-in-the-middle-metod kan hjälpa till i den här situationen.

  • Hur kan du forma en fasad som är särskilt gjord för mobilappar?

API:et för flera mikrotjänster kanske inte är väl utformat för olika klientprograms behov. Till exempel kan behoven hos en mobilapp skilja sig från behoven hos en webbapp. För mobilappar kan du behöva optimera ytterligare så att datasvar kan bli mer effektiva. Du kan göra den här funktionen genom att aggregera data från flera mikrotjänster och returnera en enda uppsättning data, och ibland eliminera data i svaret som inte behövs av mobilappen. Och du kan naturligtvis komprimera dessa data. Återigen kan en fasad eller ETT API mellan mobilappen och mikrotjänsterna vara praktiskt för det här scenariot.

Varför överväga API Gateways i stället för direkt kommunikation mellan klienter och mikrotjänster

I en arkitektur för mikrotjänster behöver klientapparna vanligtvis använda funktioner från mer än en mikrotjänst. Om förbrukningen utförs direkt måste klienten hantera flera anrop till mikrotjänstslutpunkter. Vad händer när programmet utvecklas och nya mikrotjänster introduceras eller befintliga mikrotjänster uppdateras? Om ditt program har många mikrotjänster kan det vara en mardröm att hantera så många slutpunkter från klientapparna. Eftersom klientappen skulle kopplas till dessa interna slutpunkter kan utveckling av mikrotjänster i framtiden orsaka stor påverkan för klientapparna.

Därför kan det vara praktiskt att ha en mellanliggande nivå eller nivå av indirektion (Gateway) för mikrotjänstbaserade program. Om du inte har API Gateways måste klientapparna skicka begäranden direkt till mikrotjänsterna och det ger upphov till problem, till exempel följande problem:

  • Koppling: Utan API Gateway-mönstret kopplas klientapparna till de interna mikrotjänsterna. Klientapparna måste veta hur programmets flera områden bryts ned i mikrotjänster. När de interna mikrotjänsterna utvecklas och omstruktureras påverkar dessa åtgärder underhåll eftersom de orsakar icke-bakåtkompatibla ändringar i klientapparna på grund av direktreferensen till de interna mikrotjänsterna från klientapparna. Klientappar måste uppdateras ofta, vilket gör lösningen svårare att utveckla.

  • För många turer: En enda sida/skärm i klientappen kan kräva flera anrop till flera tjänster. Den här metoden kan resultera i flera nätverksresor mellan klienten och servern, vilket ger betydande svarstid. Sammansättning som hanteras på mellannivå kan förbättra prestanda och användarupplevelse för klientappen.

  • Säkerhetsproblem: Utan en gateway måste alla mikrotjänster exponeras för den "externa världen", vilket gör attackytan större än om du döljer interna mikrotjänster som inte används direkt av klientapparna. Ju mindre attackytan är, desto säkrare kan ditt program vara.

  • Övergripande problem: Varje offentligt publicerad mikrotjänst måste hantera problem som auktorisering och SSL. I många situationer kan dessa problem hanteras på en enda nivå så att de interna mikrotjänsterna förenklas.

Vad är API Gateway-mönstret?

När du utformar och skapar stora eller komplexa mikrotjänstbaserade program med flera klientappar kan en bra metod att tänka på vara en API Gateway. Det här mönstret är en tjänst som tillhandahåller en enda startpunkt för vissa grupper av mikrotjänster. Det liknar fasadmönstret från objektorienterad design, men i det här fallet är det en del av ett distribuerat system. API Gateway-mönstret kallas ibland även för "serverdelen för klientdelen" (BFF) eftersom du skapar den när du tänker på klientappens behov.

Api-gatewayen finns därför mellan klientapparna och mikrotjänsterna. Den fungerar som en omvänd proxy och dirigerar begäranden från klienter till tjänster. Den kan också tillhandahålla andra övergripande funktioner som autentisering, SSL-avslutning och cachelagring.

Bild 4–13 visar hur en anpassad API Gateway kan passa in i en förenklad mikrotjänstbaserad arkitektur med bara några få mikrotjänster.

Diagram showing an API Gateway implemented as a custom service.

Bild 4-13. Använda en API Gateway som implementerats som en anpassad tjänst

Appar ansluter till en enda slutpunkt, API Gateway, som är konfigurerad för att vidarebefordra begäranden till enskilda mikrotjänster. I det här exemplet implementeras API Gateway som en anpassad ASP.NET Core WebHost-tjänst som körs som en container.

Det är viktigt att markera att du i diagrammet använder en enda anpassad API Gateway-tjänst som är riktad mot flera och olika klientappar. Det kan vara en viktig risk eftersom DIN API Gateway-tjänst växer och utvecklas baserat på många olika krav från klientapparna. Så småningom kommer det att bli uppsvälld på grund av dessa olika behov och effektivt kan det likna ett monolitiskt program eller monolitisk tjänst. Därför rekommenderar vi att du delar upp API Gateway i flera tjänster eller flera mindre API Gateways, till exempel en formfaktortyp per klientapp.

Du måste vara försiktig när du implementerar API Gateway-mönstret. Vanligtvis är det inte en bra idé att ha en enda API Gateway som aggregerar alla interna mikrotjänster i ditt program. Om den gör det fungerar den som en monolitisk aggregator eller orkestrerare och bryter mot mikrotjänstautonomi genom att koppla samman alla mikrotjänster.

API Gateways bör därför separeras baserat på affärsgränser och klientappar och inte fungera som en enda aggregator för alla interna mikrotjänster.

När du delar upp API Gateway-nivån i flera API Gateways, om ditt program har flera klientappar, kan det vara en primär pivot när du identifierar flera API Gateways-typer, så att du kan ha en annan fasad för varje klientapps behov. Det här fallet är ett mönster med namnet "Backend for Frontend" (BFF) där varje API Gateway kan tillhandahålla ett annat API som är anpassat för varje klientapptyp, eventuellt till och med baserat på klientformulärfaktorn genom att implementera specifik adapterkod som under anropar flera interna mikrotjänster, som visas i följande bild:

Diagram showing multiple custom API Gateways.

Bild 4-13.1. Använda flera anpassade API Gateways

Bild 4-13.1 visar API Gateways som är åtskilda efter klienttyp. en för mobila klienter och en för webbklienter. En traditionell webbapp ansluter till en MVC-mikrotjänst som använder webb-API Gateway. Exemplet visar en förenklad arkitektur med flera detaljerade API Gateways. I det här fallet baseras de gränser som identifieras för varje API Gateway enbart på BFF-mönstret (Backend for Frontend), som därför bara baseras på det API som behövs per klientapp. Men i större program bör du också gå längre och skapa andra API Gateways baserat på affärsgränser som en andra design pivot.

Huvudfunktioner i API Gateway-mönstret

En API Gateway kan erbjuda flera funktioner. Beroende på produkten kan den erbjuda rikare eller enklare funktioner, men de viktigaste och mest grundläggande funktionerna för en API Gateway är följande designmönster:

Omvänd proxy- eller gatewayroutning. API Gateway erbjuder en omvänd proxy för att omdirigera eller dirigera begäranden (layer 7-routning, vanligtvis HTTP-begäranden) till slutpunkterna för de interna mikrotjänsterna. Gatewayen tillhandahåller en enskild slutpunkt eller URL för klientapparna och mappar sedan begäranden internt till en grupp med interna mikrotjänster. Den här routningsfunktionen hjälper till att frikoppla klientapparna från mikrotjänsterna, men det är också praktiskt när du moderniserar ett monolitiskt API genom att sitta i API Gateway mellan det monolitiska API:et och klientapparna. Sedan kan du lägga till nya API:er som nya mikrotjänster samtidigt som du fortfarande använder det äldre monolitiska API:et tills det delas upp i många mikrotjänster i framtiden. På grund av API Gateway kommer klientapparna inte att märka om DE API:er som används implementeras som interna mikrotjänster eller ett monolitiskt API och ännu viktigare, när de utvecklas och omstrukturerar det monolitiska API:et till mikrotjänster, tack vare API Gateway-routningen påverkas inte klientappar med någon URI-ändring.

Mer information finns i Gateway-routningsmönster.

Aggregering av begäranden. Som en del av gatewaymönstret kan du aggregera flera klientbegäranden (vanligtvis HTTP-begäranden) som riktar sig till flera interna mikrotjänster i en enda klientbegäran. Det här mönstret är särskilt praktiskt när en klientsida/skärm behöver information från flera mikrotjänster. Med den här metoden skickar klientappen en enda begäran till API Gateway som skickar flera begäranden till de interna mikrotjänsterna och sedan aggregerar resultatet och skickar allt tillbaka till klientappen. Den största fördelen och målet med det här designmönstret är att minska chattigheten mellan klientapparna och serverdels-API:et, vilket är särskilt viktigt för fjärrappar från datacentret där mikrotjänsterna finns, till exempel mobilappar eller begäranden som kommer från SPA-appar som kommer från JavaScript i klientens fjärrwebbläsare. För vanliga webbappar som utför begäranden i servermiljön (till exempel en ASP.NET Core MVC-webbapp) är det här mönstret inte så viktigt eftersom svarstiden är mycket mindre än för fjärrklientappar.

Beroende på vilken API Gateway-produkt du använder kan den kanske utföra den här aggregeringen. I många fall är det dock mer flexibelt att skapa aggregeringsmikrotjänster under OMfånget för API Gateway, så du definierar aggregeringen i kod (d.v.s. C#-kod):

Mer information finns i Gateway-sammansättningsmönster.

Övergripande problem eller gateway-avlastning. Beroende på de funktioner som erbjuds av varje API Gateway-produkt kan du avlasta funktioner från enskilda mikrotjänster till gatewayen, vilket förenklar implementeringen av varje mikrotjänst genom att konsolidera övergripande problem till en nivå. Den här metoden är särskilt praktisk för specialiserade funktioner som kan vara komplexa att implementera korrekt i varje intern mikrotjänst, till exempel följande funktioner:

  • Autentisering och auktorisering
  • Integrering av tjänstidentifiering
  • Cachelagring av svar
  • Återförsöksprinciper, kretsbrytare och QoS
  • Hastighetsbegränsning och begränsning
  • Belastningsutjämning
  • Loggning, spårning, korrelation
  • Rubriker, frågesträngar och anspråkstransformering
  • IP-tillåtna listor

Mer information finns i Gateway-avlastningsmönster.

Använda produkter med API Gateway-funktioner

Det kan finnas många fler övergripande problem som erbjuds av API Gateways-produkterna beroende på varje implementering. Vi kommer att utforska här:

Azure API Management

Azure API Management (som visas i bild 4–14) löser inte bara dina API Gateway-behov utan tillhandahåller funktioner som att samla in insikter från dina API:er. Om du använder en API-hanteringslösning är en API Gateway bara en komponent i den fullständiga API-hanteringslösningen.

Diagram showing how to use Azure API Management as your API gateway.

Bild 4-14. Använda Azure API Management för din API Gateway

Azure API Management löser både dina API Gateway- och hanteringsbehov som loggning, säkerhet, mätning osv. I det här fallet är det faktum att du kanske har en enda API Gateway inte så riskabelt när du använder en produkt som Azure API Management, eftersom den här typen av API Gateways är "tunnare", vilket innebär att du inte implementerar anpassad C#-kod som kan utvecklas mot en monolitisk komponent.

API Gateway-produkterna fungerar vanligtvis som en omvänd proxy för inkommande kommunikation, där du också kan filtrera API:erna från de interna mikrotjänsterna plus tillämpa auktorisering på publicerade API:er på den här nivån.

De insikter som är tillgängliga från ett API Management-system hjälper dig att få en förståelse för hur dina API:er används och hur de fungerar. De utför den här aktiviteten genom att låta dig visa analysrapporter i nära realtid och identifiera trender som kan påverka ditt företag. Dessutom kan du ha loggar om begärande- och svarsaktivitet för ytterligare online- och offlineanalys.

Med Azure API Management kan du skydda dina API:er med hjälp av en nyckel, en token och IP-filtrering. Med de här funktionerna kan du framtvinga flexibla och detaljerade kvoter och hastighetsgränser, ändra formen och beteendet för dina API:er med hjälp av principer och förbättra prestanda med cachelagring av svar.

I den här guiden och referensexempelprogrammet (eShopOnContainers) är arkitekturen begränsad till en enklare och anpassad containerbaserad arkitektur för att fokusera på vanliga containrar utan att använda PaaS-produkter som Azure API Management. Men för stora mikrotjänstbaserade program som distribueras till Microsoft Azure rekommenderar vi att du utvärderar Azure API Management som bas för dina API Gateways i produktion.

Ocelot

Ocelot är en enkel API Gateway som rekommenderas för enklare metoder. Ocelot är en .NET Core-baserad API Gateway med öppen källkod som är särskilt gjord för mikrotjänstarkitekturer som behöver enhetliga startpunkter i sina system. Den är enkel, snabb och skalbar och tillhandahåller routning och autentisering bland många andra funktioner.

Den främsta anledningen till att välja Ocelot för referensprogrammet eShopOnContainers 2.0 är att Ocelot är en .NET Core lightweight API Gateway som du kan distribuera till samma programdistributionsmiljö där du distribuerar dina mikrotjänster/containrar, till exempel en Docker-värd, Kubernetes osv. Och eftersom det är baserat på .NET Core är det plattformsoberoende som gör att du kan distribuera på Linux eller Windows.

De tidigare diagrammen som visar anpassade API Gateways som körs i containrar är exakt hur du också kan köra Ocelot i en container och ett mikrotjänstbaserat program.

Dessutom finns det många andra produkter på marknaden som erbjuder API Gateways-funktioner, till exempel Apigee, Kong, MuleSoft, WSO2 och andra produkter som Linkerd och Istio för ingresskontrollantfunktioner för service mesh.

Efter den inledande arkitekturen och mönsterförklaringsavsnitten förklarar nästa avsnitt hur du implementerar API Gateways med Ocelot.

Nackdelar med API Gateway-mönstret

  • Den viktigaste nackdelen är att när du implementerar en API Gateway kopplar du den nivån till de interna mikrotjänsterna. Kopplingar som denna kan medföra allvarliga problem för ditt program. Clemens Vaster, arkitekt på Azure Service Bus-teamet, refererar till denna potentiella svårighet som "den nya ESB" i sessionen "Messaging and Microservices" på GOTO 2016.

  • Med hjälp av en API-gateway för mikrotjänster skapas ytterligare en möjlig felpunkt.

  • En API Gateway kan ge ökad svarstid på grund av det ytterligare nätverksanropet. Det här extra anropet har dock vanligtvis mindre inverkan än att ha ett klientgränssnitt som är för chattigt direkt och anropar de interna mikrotjänsterna.

  • Om den inte skalas ut korrekt kan API Gateway bli en flaskhals.

  • En API Gateway kräver ytterligare utvecklingskostnad och framtida underhåll om den innehåller anpassad logik och dataaggregering. Utvecklare måste uppdatera API Gateway för att kunna exponera varje mikrotjänsts slutpunkter. Dessutom kan implementeringsändringar i de interna mikrotjänsterna orsaka kodändringar på API Gateway-nivå. Men om API Gateway bara tillämpar säkerhet, loggning och versionshantering (som när du använder Azure API Management) kanske den här extra utvecklingskostnaden inte gäller.

  • Om API Gateway utvecklas av ett enda team kan det finnas en flaskhals i utvecklingen. Den här aspekten är en annan anledning till varför en bättre metod är att ha flera detaljerade API Gateways som svarar på olika klientbehov. Du kan också separera API Gateway internt i flera områden eller lager som ägs av de olika teamen som arbetar med de interna mikrotjänsterna.

Ytterligare resurser