Microservices är inte ett integrationsmönster
Allt som oftast brukar jag höra att man pratar om mikrotjänster (microservices) i integrationssammanhang, och ofta som en efterföljare till tjänsteorienterad arkitektur (SOA). Mikrotjänster kan vara ett väldigt användbart arkitekturmönster, men enligt min mening inte för att lösa integrationsbehov mellan olika applikationer, utan som ett sätt att dela upp monolitiska applikationer i mindre, autonoma delar som underlättar förvaltning och vidareutveckling.
- Ett stort förvaltningsteam kan ha olika expertisområden genom specialisering kring olika tjänster
- En release behöver inte medföra en ompaketering av hela systemet utan kan brytas ned i separata releasecykler per tjänst
- Gränserna för test blir mycket tydliga – en tjänst är definierad helt utifrån dess API
- Ett ökat kapacitetsbehov kan hanteras genom att distribuera tjänsterna över fler hårdvaruinstanser
Vad är en mikrotjänst?
Det finns ingen entydig definition på mikrotjänster, men oftast menar man enkla, fristående tjänster som tillsammans bygger upp ett större system. Nedan har jag listat några typiska egenskaper som brukar vara kännetecknande:
- Mikrotjänster bör vara autonoma. Med detta menar man att mikrotjänsten inkapslar alla beroenden bakom sitt externa gränssnitt. Det innebär t.ex. att varje mikrotjänst ansvarar för sin egen data.
- Mikrotjänster bör använda allmänt förekommande tekniker för att tillgängliggöra sitt gränssnitt. Gränssnittet utgörs ofta av JSON över HTTP som får anses mycket tillgängligt oavsett de kombinationer av utvecklingsspråk och operativsystem som används.
- Mikrotjänster bör vara små. Dock inte nödvändigtvis små sett till kodmängd, utan i första hand med avseende på vilken informationsdomän man hanterar. När man hanterar en begränsad informationsdomän tenderar man också att hålla nere kodmängden per tjänst.
- Mikrotjänster bör alltid vara bakåtkompatibla. Eftersom det handlar om just små och autonoma tjänster är det ofta bättre att skapa en helt ny tjänst om man finner att den befintliga informationsmodellen inte går att hålla bakåtkompatibel.
Varför inte integration mellan system?
Så varför är mikrotjänster inte något bra mönster för att bygga integrationer mellan olika system? Låt mig illustrera med ett exempel:
Antag att vi har ett kundhanteringssystem som är uppbyggt kring mikrotjänster. Vi har tjänster för kund, avtal och person – var och en autonom och utan beroenden till andra. Tittar man t.ex. på ett avtal innehåller detta bara ett abstrakt ID för kund. För att knyta ihop de olika delarna finns en webbapplikation som kommunicerar med alla mikrotjänster och kan skapa sammanhang, såsom att relatera kundinformation till ett avtal.
Figur 1: Ett fiktivt kundhanteringssystem med mikrotjänster för kund, person och avtal.
Om vi nu tänker oss att ett externt system behöver integreras för att kunna skapa privatkundsfakturor behöver man göra detta i ett antal steg: Läsa ut de olika avtalen, hämta kund för vart och ett, samt slutligen knyta respektive kund till en person.
Figur 2: Faktureringssystemet behöver hämta information från tre källor och veta hur de ska knytas samman för att kunna skapa fakturaunderlaget.
Detta upplägg är inte särskilt attraktivt, av flera anledningar:
- Fakturasystemet behöver känna till kundhanteringssystemets interna uppbyggnad och vilka olika mikrotjänster som finns tillgängliga.
- Fakturasystemet behöver själv koppla samman relaterad information, såsom kund och avtal. I detta exempel kanske inte så komplicerat, men i verkligheten kan det vara avancerad affärslogik.
- Kundhanteringssystemet exponerar alla interna gränssnitt mot omvärlden vilket komplicerar alla förändringar i kundhanteringssystemet.
- Ur säkerhetssynpunkt exponerar man en större attackyta samtidigt som man kan behöva införa auktorisering, autentisering och kryptering, vilket komplicerar både de olika mikrotjänsterna och skapar overhead för kommunikation inom systemet.
En bättre lösning
Genom att införa en komponent som exponerar ett externt API till andra system kan man säkerställa att affärslogiken inom kundhanteringsdomänen stannar där, man behöver inte exponera interna gränssnitt i onödan och kan lägga till erforderlig säkerhet utan att därför behöva pådyvla den på interna delar av systemet
Figur 3: Det externa gränssnittet samlas till en enskild punkt som kan erbjuda sammanslagna tjänster utan att i onödan exponera intern uppbyggnad.
Den nya API-komponenten kan mycket väl använda samma teknisk underbyggnad som mikrotjänsterna, exempelvis REST.
Slutsats
Det är lätt att blanda ihop begreppen när man pratar om mikrotjänster, webbtjänster, tjänsteorientering o.s.v. Mikrotjänster – trots att de ofta använder samma teknik som webbtjänster – är dock ett applikationsmönster snarare än ett integrationsmönster.