Microservices – vad är det och hur utnyttjar du det

En liten introduktion till microservices - något väldigt komplext men som kan ge väldigt bra fördelar, i vissa fall! Med hjälp av microservices kan du bland annat dela upp en applikation för ökad skalbarhet.

Vad är microservices

Enligt Wikipedia är Microservices (MSA) en variant av SOA (Service-oriented Architecture) som bygger upp en applikation av löst kopplade tjänster. Det vill säga att en applikation är uppdelad i mindre delar där varje del har en specifik funktion i applikationen. Applikationen är därmed modulär till skillnad från en monolitisk applikation som har all funktionalitet i en och samma modul. En monolitisk applikation har oftast användargränssnitt, databasaccess, lätta och tunga funktioner (avkodning/beräkningar) etc. i samma applikation. En applikation som bygger på microservices-principen delar upp de olika funktionerna i moduler där varje modul hanterar sin specifika del, t.ex. databasaccess eller det grafiska gränssnittet. Man brukar benämna varje modul som en egen tjänst. En modul som levererar en specifik funktion med tydligt definierade regler.

I många web-applikationer som använder sig av microservices används REST API och/eller meddelandeköer (t.ex. RabbitMQ) för inter-service kommunikation. Redan här kan man se skillnaden på en monolitisk struktur och microservices då latens plötsligt blir mer markant eftersom det sker kommunikation över nätverk istället för via lokalt via internminnet på servern. Nätverket blir alltså en viktig del av en microservice och är något man måste ha med i beräkningarna vid arkitekturen av en microservice.

För att hantera skalning och dela upp varje tjänst i egna isolerade delar så kan containers användas (t.ex. Docker). Om ett containerhanteringssystem används så blir det lättare att hantera skalning, redundans, failover etc. Exempel på containerhanteringssystem är bland annat Kubernetes, Docker Swarm, VMware Integrated Containers samt OpenShift (som bygger på Kubernetes).

Det finns flera aspekter att tänka på för microservices till vilka det även finns designmönster som är till för att lösa en del av dem. Det finns problem där versionshantering behöver hanteras. Systemet behöver kunna hantera olika versioner av samma modul vid exempelvis rullande uppgraderingar. De designmönster som finns för microservices är tänkt som ett hjälpmedel vid implementationen men ska heller inte ses som ett måste.

Spara resurser med microservices.

Många som sätter upp sina monolitiska applikationer på en eller flera servrar har ofta mer resurser allokerade än vad som någonsin används. I vissa fall kan det vara av nytta för att hantera spikar i lasten. Men även då betalar man för mer resurser än vad man utnyttjar den övriga tiden. Med microservices och containers kan man skala horisontellt och öka på med fler containers för den del av tjänsten som vid tillfället kräver mer last. Varje container i sig har ett visst antal resurser tilldelade men långt ifrån lika mycket resurser som en monolitisk applikation har på en server. Skalar man sedan ner antal containers när lasten minskar så allokerar man inte lika mycket resurser i onödan. Har man även microservices tänk så behövs bara den del av tjänsten som kräver mer resurser skalas och inte alla delar vilket även där sparar mycket resurser. Om en applikation inte behöver skalas så kan dock microservices med containers medföra en viss overhead eftersom varje del av applikationen kräver en viss overhead i form av minne och disk i sin container (t.ex. ruby kräver ruby-tolken i varje container). Men behöver man inte skala applikationen så bör man nog tänka igenom ifall microservices verkligen behöver användas.

 

MICROSERVICES PÅ TECH DAYS

Vill du veta mer om microservices, containers och hur de kan hjälpa just dig i din vardag? Besök Tech Days i april där Magnus B. Persson från Cygate kommer att prata om just detta ämne.

Läs mer om Tech Days

 

Fördelar med microservices

  • Tydlig uppdelning av funktionalitet
  • Enklare att skala då det sker per tjänst
  • Utnyttjar resurser mer effektivt vid toppar av högre last (kan sänka kostnader för resurser i form av hårdvara)
  • Enkelt att byta ut tjänsterna (modulerna) om de följer samma protokoll
  • De olika tjänsterna kan utvecklas i olika programspråk som passar dess ändamål bäst.
  • Varje tjänst kan deployas var för sig och uppdateringar kan då ske per modul och inte hela systemet (applikationen).
  • Olika databaser kan användas och även enklare bytas ut.
  • Passar bra för ”DevOps” metodologin.
  • Enkelt att utföra många tester per modul (vältestad kod).
  • Man kan bygga applikationen så att om en tjänst kraschar så kraschar inte hela applikationen. Det finns ett designmönster som kallas Circuit Breaker som är tänkt att adressera detta problem.
  • Enkelt att rulla tillbaka tidigare versioner av enskilda tjänster vid problem.
  • Tung last kan läggas på bättre hårdvara medan moduler som inte kräver lika hög prestanda kan köras på annan hårdvara.

Nackdelar med microservices

  • Informationsspridning blir svårare mellan de olika modulerna.
  • Latens mellan de olika modulerna pga nätverkslast, protokoll-overhead etc.
  • Nätverket blir väldigt viktigt och kan innebära single point of failure.
  • Systemtest kan bli svårare då det är ett stort system
  • Kan bli för små moduler (”nanoservices”) som utnyttjar mer resurser än vad funktionaliteten tillför.
  • Kan vara svårare att övervaka
  • Hantering av konfiguration kan bli utspridd (måste hanteras på något sätt).
  • Service-discovery måste hanteras så att alla tjänster kan nå alla andra tjänster i applikationen. Även hantering vid skalning måste ske via service-discovery så att man enkelt kan lägga till nya resurser vid horisontell skalning (dvs flera instanser av samma tjänst).
  • Omstrukturering kan bli ett stort jobb ifall varje tjänst utvecklas av olika grupper och man behöver flytta kod/funktion mellan grupperna.
  • Kräver djup kunskap av utvecklare för att hantera alla delar (containers, utveckling, automation, monitorering, orkestrering etc)

Företag som använder microservices

Det finns flera stora företag som bygger sina tjänster med microservices för att hantera den stora last och komplexa systembild som deras tjänster medför.

Netflix är kanske den mest kända av företagen för oss i Sverige. Men även Zalando (kläder/mode), Uber (Taxi), Amazon, Google, samt Ebay (auktion/shop) använder sig av Microservices för sina tjänster.

Netflix är även en stor bidragsgivare till open source-världen då de släpper mycket av sin kod öppen på Github. I deras källkodsarkiv kan man tydligt se att deras olika tjänster är skrivna i olika programspråk så som Go, Scala, Python, Java, C++, Ruby, C etc. vilket fungerar bra då de bygger på microservices-arkitektur.

Exempel på microservice

Om vi tänker oss att vi ska bygga en tjänst som ska hantera bilder åt fotografer där varje fotograf har ett eget konto och kan ladda upp sina bilder i vilket format de vill och sedan publicera på websidan som kan nås dels via webläsare och dels via en mobil-app.

Om vi bryter ner delarna på vad som behövs kan vi komma fram till att vi behöver:

  • Web-UI som presenterar html/javascript.
  • Användardatabas (MySQL)
  • Bilddatabas (med objektlagring via Ceph)
  • Konvertering av bilder till thumbnails/olika storlekar/olika format.
  • API för mobil-app

Vi kan då skapa 5 moduler(tjänster). En modul som hanterar grafiska interfacet och går via samma API som vår mobil-app, vilket medför att båda fungerar på samma sätt men presenterar olika mot användaren. En modul som hanterar användare (skapa, uppdatera, hämta etc). En bild-modul som hanterar alla bilder i olika format och versioner samt en modul som hanterar konvertering av bilder från olika format till nya format och olika storlekar. Till sist en modul som har ett API som både mobil-appen och websidan använder sig av.

RabbitMQ kan användas för att låta bildhanteringsmodulen lägga upp förfrågningar i en RabbitMQ kö som sedan processas av bildkonverteringsmodulen. Varje modul kan skalas horisontellt och service-discovery/lastbalanseringsmodulen ser till att lasten hanteras korrekt mellan de olika instanserna.

Ett enkelt diagram över vår lilla microservice skulle kunna se ut så här:

Vad behövs för att komma igång

Så vad behövs egentligen för att komma igång med microservices. Många delar som behövs finns redan färdiga i flera olika ramverk som hjälper till med bland annat service-discovery, övervakning etc. Containers passar väldigt bra för microservices, så som Docker och Kubernetes för hantering av containers. För RPC finns det färdiga meddelandeköer som går att använda (t.ex. RabbitMQ).

Slutsats

Microservices är väldigt komplext men kan ge väldigt bra fördelar, i vissa fall! Det gäller egentligen att veta när man ska bygga sin tjänst från ett microservices-perspektiv eller inte.

Det viktigaste är att analysera sin tjänst och se om microservices tänket verkligen passar den tjänst som ska utvecklas. I vissa fall passar en monolitisk applikation mycket bättre. I andra fall kanske Function as a Service passar bättre för att avlasta ett fåtal funktioner från sin applikation (t.ex. för att avkoda video, konvertera bilder etc).

Det finns heller inget spikat sätt att skapa microservices på. Man kan egentligen bygga delar av en tjänst med microservices tänk och andra med monolitiskt tänk. Det viktigaste är att man tänker igenom alla möjliga problem som man endera löser eller kanske tillför beroende på vilken metod man väljer att använda.

Länkar