Arkitekturformat för mikrotjänster
En arkitektur för mikrotjänster består av en samling små, autonoma tjänster. Varje tjänst är fristående och bör implementera en enda affärsfunktion i en begränsad kontext. En avgränsad kontext är en naturlig division inom ett företag och ger en explicit gräns inom vilken en domänmodell finns.
Vad är mikrotjänster?
Mikrotjänster är små, oberoende och löst kopplade. En liten grupp utvecklare ska kunna skriva och underhålla en sådan tjänst.
Varje tjänst utgör en separat kodbas som kan hanteras av ett litet utvecklingsteam.
Tjänster kan distribueras oberoende av varandra. Ett team kan uppdatera en befintlig tjänst utan att bygga om och omdistribuera hela programmet.
Tjänsterna svarar för att spara sina egna data eller externa tillstånd. Detta skiljer sig från den traditionella modellen, där ett separat datalager hanterar datapersistensen.
Tjänster kommunicerar med varandra med hjälp av väldefinierade API:er. Interna implementeringsdetaljer för varje tjänst är dolda från andra tjänster.
Stöder flerspråkig programmering. Tjänster behöver till exempel inte dela samma teknikstack, bibliotek eller ramverk.
Förutom tjänsterna själva visas vissa andra komponenter i en typisk mikrotjänstarkitektur:
Hantering/orkestrering. Den här komponenten ansvarar för att placera tjänster på noder, identifiera fel, ombalansera tjänster över flera noder och så vidare. Den här komponenten består vanligtvis av en startklar teknik, till exempel Kubernetes, i stället för något som är anpassat.
API-gateway. API-gatewayen är startpunkten för klienterna. I stället för att anropa tjänsten direkt anropar klienten API-gatewayen, som vidarebefordrar anropet till rätt tjänster på serverdelen.
Fördelarna med att använda en API-gateway är bland annat följande:
Den frikopplar klienter från tjänster. Tjänsterna kan versionshanteras eller omstruktureras utan att alla klienter behöver uppdateras.
Tjänsterna kan använda meddelandeprotokoll som inte är webbvänliga, till exempel AMQP.
API-gatewayen kan utföra andra övergripande funktioner, till exempel autentisering, loggning, SSL-avslutning och belastningsutjämning.
Färdiga principer, till exempel för begränsning, cachelagring, transformering eller validering.
Fördelar
Flexibilitet. Eftersom mikrotjänster distribueras oberoende av varandra är det enklare att hantera felkorrigeringar och funktionsutgåvor. Du kan uppdatera en tjänst utan att omdistribuera hela programmet, och återställa en uppdatering om något blir fel. Om en bugg hittas i en del av programmet i många traditionella program kan den blockera hela lanseringsprocessen. Nya funktioner kan fördröjas i väntan på att en felkorrigering ska integreras, testas och publiceras.
Små, fokuserade team. En mikrotjänst bör vara tillräckligt liten för att ett enda funktionsteam ska kunna skapa, testa och distribuera den. Små teamstorlekar främjar mer flexibilitet. Stora grupper tenderar att vara mindre produktiva eftersom kommunikationen är långsammare, hanteringskostnaderna ökar och flexibiliteten minskar.
Liten kodbas. I ett monolitiskt program finns det en tendens att kodberoenden blir sammanflätade över tid. Att lägga till en ny funktion kräver att du trycker på kod på många platser. Eftersom en arkitektur för mikrotjänster inte delar kod eller datalager minimeras beroenden, vilket gör det enklare att lägga till nya funktioner.
Blandning av tekniker. Team kan välja den teknik som bäst passar deras tjänst med en blandning av teknikstackar efter behov.
Felisolering. Om en enskild mikrotjänst blir otillgänglig stör den inte hela programmet, förutsatt att alla överordnade mikrotjänster är utformade för att hantera fel korrekt. Du kan till exempel implementera kretsbrytarmönstret, eller så kan du utforma din lösning så att mikrotjänsterna kommunicerar med varandra med hjälp av asynkrona meddelandemönster.
Skalbarhet. Tjänsterna kan skalas oberoende av varandra, vilket gör att du kan skala ut delsystem som kräver mer resurser utan att skala ut hela programmet. Med hjälp av en orkestrerare som Kubernetes kan du packa en högre densitet av tjänster på en enda värd, vilket möjliggör effektivare användning av resurser.
Dataisolering. Det är mycket enklare att utföra schemauppdateringar eftersom endast en mikrotjänst påverkas. I ett monolitiskt program kan schemauppdateringar bli mycket utmanande eftersom olika delar av programmet kan röra samma data, vilket gör eventuella ändringar i schemat riskfyllda.
Utmaningar
Fördelarna med mikrotjänster är dock inte gratis. Här är några av utmaningar du bör tänka på när du väljer en arkitektur för dina mikrotjänster.
Komplexitet. Ett mikrotjänstprogram har fler rörliga delar än motsvarande monolitiska program. Varje tjänst är enklare, men hela systemet som helhet är mer komplext.
Utveckling och testning. Att skriva en liten tjänst som förlitar sig på andra beroende tjänster kräver en annan metod än att skriva ett traditionellt monolitiskt eller skiktat program. Befintliga verktyg är inte alltid utformade att fungera med tjänstberoenden. Det kan vara svårt att omstrukturera över tjänstgränser. Det är även svårt att testa tjänstens beroenden, i synnerhet när programmet utvecklas snabbt.
Brist på styrning. Den decentraliserade metoden för att skapa mikrotjänster har fördelar, men det kan också leda till problem. Du kan få så många olika språk och ramverk att programmet blir svårt att underhålla. Det kan vara bra att införa vissa projektomfattande standarder, utan att alltför begränsa teamens flexibilitet. Detta gäller särskilt för övergripande funktioner, till exempel loggning.
Nätverksbelastning och svarstid. Användningen av många små, detaljerade tjänster kan leda till mer kommunikation mellan tjänster. Även om kedjan av tjänsteberoenden blir för lång (tjänst A anropar B, som anropar C osv.), kan den förlängda svarstiden bli ett problem. Du behöver designa API:erna noggrant. Undvik alltför pratsamma API:er, tänk på serialiseringsformat och leta efter platser där du kan använda asynkrona kommunikationsmönster som köbaserad belastningsnivå.
Dataintegritet. Varje mikrotjänst ansvarar för sin egen datapersistence. Därför kan datakonsekvens mellan flera tjänster vara en utmaning. Olika tjänster bevarar data vid olika tidpunkter, med hjälp av olika teknik och med potentiellt olika framgångsnivåer. När fler än en mikrotjänst är involverad i att bevara nytt eller ändrat datum är det osannolikt att den fullständiga dataändringen kan betraktas som en ACID-transaktion. I stället är tekniken mer anpassad till BASE (i princip tillgänglig, mjukt tillstånd och så småningom konsekvent). Använd eventuell konsistens där det är möjligt.
Hantering. För att lyckas med mikrotjänster krävs en mogen DevOps-kultur. Korrelerad loggning mellan tjänster kan vara utmanande. Loggning måste vanligtvis korrelera flera tjänstanrop för en enskild användaråtgärd.
versionshantering. Uppdateringar av en tjänst får inte bryta tjänster som är beroende av den. Flera tjänster kan uppdateras när som helst, så utan noggrann design kan du få problem med bakåt- eller framåtkompatibilitet.
Kunskaper. Mikrotjänster är mycket distribuerade system. Utvärdera noggrant om teamet har de kunskaper och den erfarenhet som behövs för att lyckas.
Metodtips
Modellera tjänster runt affärsdomänen.
Decentralisera allt. Enskilda team ansvarar för att utforma och bygga tjänster. Undvik att dela kod eller datascheman.
Datalagring ska vara privat för den tjänst som äger data. Använd den bästa lagringen för varje tjänst och datatyp.
Tjänster kommunicerar via väl utformade API:er. Undvik att läcka implementeringsinformation. API:er bör modellera domänen, inte den interna implementeringen av tjänsten.
Undvik koppling mellan tjänster. Orsaker till koppling är delade databasscheman och fasta kommunikationsprotokoll.
Avlasta övergripande problem, till exempel autentisering och SSL-avslutning, till gatewayen.
Håll domänkunskapen borta från gatewayen. Gatewayen ska hantera och dirigera klientbegäranden utan någon kunskap om affärsregler eller domänlogik. Annars blir gatewayen ett beroende och kan orsaka koppling mellan tjänster.
Tjänsterna bör ha lös koppling och hög funktionell sammanhållning. Funktioner som sannolikt kommer att ändras tillsammans bör paketeras och distribueras tillsammans. Om de finns i separata tjänster blir tjänsterna nära kopplade, eftersom en ändring i en tjänst kräver att den andra tjänsten uppdateras. Alltför pratsam kommunikation mellan två tjänster kan vara ett symptom på nära koppling och låg sammanhållning.
Isolera fel. Använd återhämtningsstrategier för att förhindra fel i en tjänst från att sammanhängande. Se Återhämtningsmönster och Designa tillförlitliga program.
Nästa steg
Detaljerad vägledning om hur du skapar en mikrotjänstarkitektur i Azure finns i Designa, skapa och använda mikrotjänster i Azure.