Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
En av de största utmaningarna med mikrotjänster är att definiera gränserna för enskilda tjänster. Den allmänna regeln är att en tjänst bara ska göra en sak, men att tillämpa den regeln i praktiken kräver noggrann eftertanke. Det finns ingen mekanisk process som ger rätt design. Du måste tänka djupt på din affärsdomän, krav, arkitekturegenskaper (även kallade icke-funktionella krav) och mål. Annars kan du få en slumpmässig design som uppvisar vissa oönskade egenskaper, till exempel dolda beroenden mellan tjänster, nära koppling eller dåligt utformade gränssnitt. Den här artikeln visar en domändriven metod för att utforma mikrotjänster. Att utvärdera tjänstgränser är ett pågående arbete med att utveckla arbetsbelastningar. Ibland resulterar utvärderingen i omdefinierade definitioner av befintliga gränser som kräver mer programutveckling för att hantera ändringarna.
Den här artikeln använder en drönarleveranstjänst som ett återkommande exempel. Mer information om scenariot och motsvarande referensimplementering finns i Designa en arkitektur för mikrotjänster.
Introduktion
Mikrotjänster bör utformas kring affärsfunktioner, inte horisontella lager som dataåtkomst eller meddelanden. Dessutom bör de ha lös koppling och hög funktionell sammanhållning. Mikrotjänster är löst kopplade om du kan ändra en tjänst utan att kräva att andra tjänster uppdateras samtidigt. En mikrotjänst är sammanhängande om den har ett enda, väldefinierat syfte, till exempel att hantera användarkonton eller spåra leveranshistorik. En tjänst bör kapsla in domänkunskap och sammanfatta den kunskapen från klienter. En klient bör till exempel kunna schemalägga en drönare utan att känna till information om schemaläggningsalgoritmen eller hur drönarflottan hanteras. Arkitekturegenskaper måste definieras för varje mikrotjänst för att matcha dess domänproblem, i stället för att definieras för hela systemet. En kundinriktad mikrotjänst kan till exempel behöva ha prestanda, tillgänglighet, feltolerans, säkerhet, testbarhet och flexibilitet. En serverdelsmikrotjänst kan bara behöva ha feltolerans och säkerhet. Om mikrotjänster har synkron kommunikation med varandra skapar beroendet mellan dem ofta behovet av att dela samma arkitekturegenskaper.
Med domändriven design (DDD) får du ett ramverk som du kan använda för att få ut det mesta möjliga av en uppsättning väldesignade mikrotjänster. DDD har två distinkta faser, den strategiska och den taktiska. I strategisk DDD definierar du systemets storskaliga struktur. Strategisk DDD hjälper till att säkerställa att arkitekturen behåller fokuset på affärsfunktioner. Taktisk DDD ger en uppsättning designmönster som du kan använda för att skapa domänmodellen. Dessa mönster inkluderar entiteter, aggregat och domäntjänster. Dessa taktiska mönster hjälper dig att utforma mikrotjänster som både är löst kopplade och sammanhängande.
I den här artikeln och i nästa steg går vi igenom följande steg och tillämpar dem på drone delivery-programmet:
Börja med att analysera företagsdomänen för att förstå programmets funktionskrav. Resultatet av det här steget är en informell beskrivning av domänen som kan förfinas till en mer formell uppsättning domänmodeller.
Definiera sedan domänens avgränsade kontexter . Varje avgränsad kontext innehåller en domänmodell som representerar en viss underdomän i det större programmet.
I en avgränsad kontext använder du taktiska DDD-mönster för att definiera entiteter, aggregat och domäntjänster.
Använd resultaten från föregående steg för att identifiera mikrotjänsterna i ditt program.
I den här artikeln går vi igenom de tre första stegen, som främst handlar om DDD. I nästa artikel ska vi identifiera mikrotjänsterna. Det är dock viktigt att komma ihåg att DDD är en iterativ, pågående process. Tjänstgränser är inte fasta i sten. När ett program utvecklas kan du välja att dela upp en tjänst i flera mindre tjänster.
Kommentar
Den här artikeln visar inte en fullständig eller omfattande domänanalys. Vi höll avsiktligt exemplet kort för att illustrera huvudpunkterna. För mer bakgrund om DDD rekommenderar vi Eric Evans Domain-Driven Design, boken som först introducerade termen. En annan bra referens är Implementering Domain-Driven Design av Vaughn Vernon.
Scenario: Drönarleverans
Fabrikam, Inc. startar en tjänst för drönarleverans. Företaget hanterar en flotta med drönare. Företag registrerar sig för tjänsten och användare kan begära att en drönare hämtar gods för leverans. När en kund schemalägger en hämtning tilldelar ett serverdelsystem en drönare och meddelar användaren en uppskattad leveranstid. När leveransen pågår kan kunden spåra drönarens plats med en ständigt uppdaterad ETA (beräknad ankomst).
Det här scenariot innehåller en ganska komplex domän. Några av de viktigaste affärsproblemen är schemaläggning av drönare, spårningspaket, hantering av användarkonton och lagring och analys av historiska data. Fabrikam strävar också efter att snabbt komma ut på marknaden och iterera snabbt och lägga till nya funktioner och funktioner. Programmet måste fungera i molnskala och uppfylla ett högt servicenivåmål. Fabrikam förväntar sig också att olika delar av systemet har olika krav för datalagring och frågor. Dessa överväganden gör att Fabrikam använder en mikrotjänstarkitektur för drone delivery-programmet.
Analysera domänen
En DDD-metod hjälper dig att utforma mikrotjänster så att varje tjänst passar perfekt för ett funktionellt affärsbehov. Det kan hjälpa dig att undvika fällan att låta organisationens gränser eller teknikval diktera din design.
Innan du skriver någon kod bör du ha en övergripande förståelse för systemet som du skapar. DDD börjar med att modellera företagsdomänen och skapa en domänmodell. Domänmodellen är en abstrakt modell för företagsdomänen. Det destillerar och organiserar domänkunskap och ger ett gemensamt språk för utvecklare och domänexperter.
Börja med att mappa alla affärsfunktioner och deras anslutningar. Det här arbetet kan vara ett samarbete som omfattar domänexperter, programvaruarkitekter och andra intressenter. Du behöver inte använda någon särskild formalitet. Skissa ett diagram eller rita på en whiteboardtavla.
När du fyller i diagrammet kan du börja identifiera diskreta underdomäner. Vilka funktioner är nära relaterade? Vilka funktioner är centrala för verksamheten och vilka funktioner tillhandahåller kompletterande tjänster? Vad är beroendediagrammet? Under den här inledande fasen är du inte intresserad av tekniker eller implementering. Med detta sagt bör du notera den plats där programmet behöver integreras med externa system, till exempel hantering av kundrelationer, betalningsbearbetning eller faktureringssystem.
Exempel: Program för drönarleverans
Efter en inledande domänanalys kom Fabrikam-teamet fram till en grov skiss som visar domänen Drone Delivery.
- Frakt placeras i mitten av diagrammet eftersom det är kärnan i verksamheten. Allt annat i diagrammet finns för att aktivera den här funktionen.
- Drönarhantering är också kärnan i verksamheten. Funktioner som är nära relaterade till drönarhantering inkluderar drönarreparation och användning av förutsägelseanalys för att förutsäga när drönare behöver service och underhåll.
- ETA-analys ger tidsuppskattningar för upphämtning och leverans.
- Med transport från tredje part kan programmet schemalägga alternativa transportmetoder om ett paket inte kan levereras helt med drönare.
- Drönardelning är en möjlig förlängning av kärnverksamheten. Företaget kan ha överskott av drönarkapacitet under vissa timmar och kan hyra ut drönare som annars skulle vara inaktiva. Den här funktionen finns inte i den första versionen.
- Videoövervakning är ett annat område som företaget kan expandera till senare.
- Användarkonton, fakturering och callcenter är underdomäner som stöder kärnverksamheten.
Observera att vi i det här läget inte har fattat några beslut om implementering eller teknik. Vissa av undersystemen kan omfatta externa programvarusystem eller tjänster från tredje part. Trots detta måste programmet interagera med dessa system och tjänster, så det är viktigt att inkludera dem i domänmodellen.
Kommentar
När ett program är beroende av ett externt system finns det en risk att det externa systemets dataschema eller API kan läcka in i programmet. Den här typen av läckage kan äventyra arkitekturdesignen. Det är särskilt vanligt med äldre system som inte följer moderna metodtips och som kan använda invecklade datascheman eller inaktuella API:er. I dessa fall är det viktigt att upprätta en väldefinierad gräns mellan det externa systemet och programmet. Överväg att använda Strangler Fig-mönstret eller Antikorruptionslager-mönstret för att framtvinga den här gränsen.
Definiera avgränsade kontexter
Domänmodellen kommer att innehålla representationer av verkliga saker – användare, drönare, paket och så vidare. Men det betyder inte att alla delar av systemet behöver använda samma representationer för samma saker.
Till exempel måste undersystem som hanterar drönarreparation och förutsägelseanalys representera många fysiska egenskaper hos drönare, till exempel deras underhållshistorik, körsträcka, ålder, modellnummer, prestandaegenskaper och så vidare. När vi ska schemalägga en leverans behöver vi dock inte tänka på de här sakerna. Undersystemet för schemaläggning behöver bara veta om en drönare är tillgänglig samt beräknad tid för upphämtning och leverans.
Om vi försöker skapa en enskild modell för båda dessa undersystem blir det onödigt komplext. Det skulle även bli svårare för modellen att utvecklas med tiden, eftersom eventuella ändringar måste fungera för flera team som arbetar med separata undersystem. Därför är det ofta bättre att utforma separata modeller som representerar samma verkliga entitet (i det här fallet en drönare) i två olika kontexter. Varje modell innehåller bara de funktioner och attribut som är relevanta i just den modellens kontext.
DDD-begreppet avgränsade kontexter spelar in här. En begränsad kontext definierar gränsen inom en domän där en specifik domänmodell gäller. Med hänvisning till föregående diagram kan du gruppera funktioner baserat på om olika funktioner delar samma domänmodell.
Avgränsade kontexter är inte nödvändigtvis isolerade från varandra. I det här diagrammet representerar de fasta linjer som ansluter de avgränsade kontexterna platser där två avgränsade kontexter interagerar. Leverans är till exempel beroende av användarkonton för att få information om kunder och på Drönarhantering för att schemalägga drönare från flottan.
I boken Domain Driven Design beskriver Eric Evans flera mönster för att upprätthålla integriteten hos en domänmodell när den interagerar med en annan begränsad kontext. En av huvudprinciperna för mikrotjänster är att tjänster kommunicerar via väldefinierade API:er. Den här metoden motsvarar två mönster som Evans kallar "Open Host Service" och "Published Language." Tanken med Open Host Service är att ett undersystem definierar ett formellt protokoll (API) för andra undersystem att kommunicera med det. Publicerat språk utökar den här idén genom att publicera API:et i ett formulär som andra team kan använda för att skriva klienter. I artikeln Designa API:er för mikrotjänster diskuterar vi att använda OpenAPI Specification (tidigare kallat Swagger) för att definiera språkagnostiska gränssnittsbeskrivningar för REST-API:er, uttryckta i JSON- eller YAML-format.
Under resten av den här resan kommer vi att fokusera på den fraktgränsade kontexten.
Nästa steg
När du har slutfört en domänanalys är nästa steg att tillämpa taktisk DDD för att definiera dina domänmodeller med större precision.