Microservices is een enorme hype in de software architectuur. Het is een architectuurstijl waarvan organisaties geloven dat het de heilige graal is om stabiele, makkelijk te onderhouden en goedkopere systemen te ontwikkelen. Omdat er net zoveel definities van Microservices zijn als architectuurstijlen, bestaat het gevaar dat er niet van alle voordelen gebruik gemaakt wordt. Zonde, als het aan de experts ligt. Daarom hier de 10 dingen die je echt moet weten over Microservices.
1. Wat is een Microservice nu eigenlijk?
Volgens Martin Fowler is de Microservice Architectuur een stijl waarbij een applicatie bestaat uit meerdere services die samen een geheel vormen.
In het kort is de microservice architectuur stijl een manier om een enkele applicatie te ontwikkelen in de context van een verzameling kleinere services, ieder met zijn eigen proces en gekoppeld via lichtgewicht mechanismen zoals HTTP.
Er is een zeer beperkt management nodig van een Microservice waardoor er vrijheid van een technische implementatie is. Een Microservice is ook verantwoordelijk voor het opslaan van de gegevens. Hoe deze gegevens worden opgeslagen is ook een vrijheid en is niet centraal vastgelegd. Het team wordt hierdoor wel verantwoordelijk voor beheer en incident management. Dit moet je misschien even twee keer lezen. Een beeld zegt meer dan heel veel woorden: Sam Newman visualiseert de Microservice heel verhelderend als een bijenkorf.
2. “The Monolith”
Een monoliet is een grote steen. Een ondoordringbaar ding. Het refereert aan een architectuur die vaak bestaat uit drie lagen. Dit zijn de presentatielaag, de businesslaag en de datalaag. De applicatie is operationeel in een enkel proces en bij iedere wijziging wordt de hele applicatie opnieuw gereleased in een nieuwe versie.
De huidige applicaties die worden ontwikkeld in opdrachten maken gebruik van deze manier. Overigens geen verkeerde keuze. Deze stijl kan in de toekomst prima blijven werken, ook voor nieuwe instanties van systemen. Alleen kunnen applicaties hierdoor na verloop van tijd onhandelbaar worden. Want door toevoeging van functionaliteiten stijgt de complexiteit en daalt de efficiency. Zo kan het gebeuren dat het 45 minuten duurt voor een applicatie is gecompiled. Of dat verschillende onderdelen zo afhankelijk van elkaar zijn dat het te lang duurt om succesvol wijzigingen of uitbreidingen uit te voeren.
Die complexitieit gaan we tegenwoordig op verschillende manieren te lijf, bijvoorbeeld door de Scrum werkwijze waarin autonome teams werken aan kleine onderdelen.
Deze frustraties zijn de aanleiding geweest voor het ontstaan van de Microservice architectuur.
3. Bounded Context
Waar ligt de grens van een Microservice? Omdat er geen voorgeschreven regel bestaat kijken we vooral naar de grenzen binnen de organisatie.
Om een model te maken van een organisatie ontstaan er meerdere betekenissen van dezelfde term. Zo heeft een ‘klant’ andere eigenschappen binnen de finance afdeling dan een klant binnen het magazijn. Een organisatie heeft afdelingen met eigen verantwoordelijkheden. Het model van een organisatieonderdeel wordt ook wel een ‘Bounded Context’ genoemd. Software die gericht is op deze context heeft het voordeel dat het niet snel in conflicteert met omgrenzende context. Deze grenzen worden ook opgezocht bij het definiëren van Microservices. Op deze manier zijn teams verantwoordelijk voor een stuk organisatieonderdeel. Als er gegevens uitgewisseld moeten worden tussen deze grenzen dan betekent dit dus dat teams moeten communiceren voor het bepalen van de gedeelde informatie. Deze gedeelde informatie wordt ook wel het ‘Shared Model’ genoemd.
4. Omvang van een Microservice
Er bestaat geen regel over hoeveel code er in een service aanwezig is. Daarom is het goed is om te kijken naar de omvang van het team. Een enkel team zou in staat moeten zijn om een Microservice te bouwen en te onderhouden. Een mooie referentie is scrum waar duidelijke grenzen worden aangegeven van het aantal ontwikkelaars in een team. Als een Microservice onhandelbaar wordt voor een team waardoor het niet meer mogelijk is om regelmatig een release te doen, dan is dit een goede indicatie dat de Microservice opgesplitst moet worden. Binnen de Bounded Context zijn waarschijnlijk meerdere contexten aanwezig. Een finance afdeling heeft bijvoorbeeld een onderdeel dat bezig is met inkoop en een onderdeel dat zich richt op facturering.
5. Onafhankelijke releases zijn een voorwaarde
Het is wat mij betreft een harde eis dat een Microservice los van andere services te releasen is. Het hele concept gaat er vanuit dat de afhankelijkheden tot een minimum beperkt worden. De integratie tussen Microservices is uitsluitend via de afgesproken (REST) interfaces. Een goed voorbeeld van integratie is de Database. Als twee Microservices via dezelfde Database integreren dat is er een sterke integratie die er zomaar voor kan zorgen dat onafhankelijke releases niet meer mogelijk zijn.
6. Team autonomie en technische vrijheid
Microservices gaat goed samen met autonome agile teams. Teams hebben de vrijheid in het maken van keuzes die te maken hebben met de inrichting van de Microservice aan de binnenkant. Hierdoor wordt het mogelijk om een Java team en een .NET team aan dezelfde toepassing te laten werken. Omdat de teams verantwoordelijk zijn voor de Bounded Context is het ook mogelijk om een eigen techniek in data opslag te kiezen. Ik denk dat data integratie hierdoor minder snel mogelijk wordt. Ik verwacht wel dat enige afstemming nodig is om niet tegen onnodige licentiekosten aan te lopen als iedere Microservice een eigen dataopslag kiest.
7. Standaardisatie interfacing, logging en monitoring
Differentiëren aan de binnenkant en standaardiseren aan de buitenkant. Dit principe zorgt ervoor dat teams de volledige vrijheid hebben in de techniek maar dat communicatie tussen de services wel volgens afspraken gebeurt. Ik zie hier ook een grote rol voor de architect. De architect bepaalt een blauwdruk waar services aan moeten voldoen om traceerbaarheid, performance en efficiëntie hoog in het vizier te houden. Om de traceerbaarheid te verhogen kan het bijvoorbeeld verplicht worden voor een Microservice om met correlatie sleutels te werken. Om de efficiëntie te verhogen kunnen Microservices bijvoorbeeld gebruik maken van connection pooling of circuit breakers. Daarnaast moet een bepaald logging format worden aangehouden om een geaggregeerd overzicht te maken over meerdere Microservices heen.
8. Scaffolding & Continuous Delivery
Aangezien er toch wel wat eisen kunnen worden gesteld waar een Microservice aan moet voldoen (logging, monitoring en interfacing) ontstaat de wens naar een blauwdruk. Een organisatie moet in staat zijn om snel te schakelen. Het inrichten van scaffolding is hierdoor een vereiste. Scaffolding is het in de steigers krijgen van een nieuwe instantie. Binnen een aantal uur moet een nieuwe Microservice aan te maken zijn binnen het landschap. Ik las laatst dit artikel van een organisatie die een chatbot had ingericht om zo snel nieuwe instanties van Apps te initiëren. Daarnaast is het een harde eis dat Microservices via automatische scripts op de verschillende omgevingen kunnen worden geplaatst. Hierdoor is het mogelijk om grip op de kwaliteit te houden, een korte time-to-market te halen en integratieverschillen tot een minimum te beperken. Ik denk dat het in de praktijk toch erg moeilijk gaat worden om de verschillende versies van Microservices te beheren. Een organisatie zal in ieder geval zwaar moeten investeren in Continuous Delivery en geautomatiseerde releases.
9. Wel of geen ‘Monolith First’ aanpak?
Een veelbesproken aanpak is de ‘Monolith First’ aanpak: een team begint aan het bouwen van een enkele grote, allesomvangrijke applicatie. Zodra de applicatie te complex wordt zijn er bepaalde symptomen zichtbaar. Het duurt bijvoorbeeld een uur om te releasen, een ontwikkelmachine moet beschikken over enorm veel geheugen of er werken een aantal teams aan een applicatierelease. De aanpak gaat er vanuit dat er op dit moment Microservices worden gevormd uit de applicatie. Hierdoor kunnen gespecialiseerde teams weer werken aan een losse applicatie of een onderdeel daarvan.
Ik geloof niet heel erg in deze aanpak omdat de complexiteit al een gegeven is op het moment dat de behoefte voor Microservices ontstaat. Ik zag laatst een mooie metafoor van een moestuin. Bij het opmaken van een moestuin in maart heb je mooie vakken bepaald waar de groenten en fruit komen. In de praktijk is het na de zomervakantie een grote spaghetti van wortels en takken waar geen vakken meer in te vinden zijn. Ga hier maar eens de tomaten uit loshalen en overpotten. Kortom, dan is het eigenlijk al te laat. Het is in mijn ogen beter om in een eerdere fase voor deze aanpak te kiezen voordat de symptomen zichtbaar zijn.
Ik ben het er ook niet mee eens dat een architectuur vanaf de eerste dag van services gebruik moet maken. Ik verwijs naar een agile principe waar gestuurd wordt op ‘net goed genoeg’. De waarde van een initiatief moet bewezen worden voor het een succes is.
Organisaties die tegen symptomen aanlopen kunnen een tactiek kiezen waarbij de monoliet langzaam wordt omgevormd naar een Microservice architectuur. Het komt voor dat er nog een monoliet overblijft in de kern maar nieuwe initiatieven worden dan doorontwikkeld in de services. Opnieuw beginnen aan een volledig nieuwe opzet is natuurlijk ook een tactiek. Een nadeel hier is de datamigratie naar het nieuwe landschap.
10. De voordelen van Microservices
De belangrijkste voordelen van Microservices zijn:
- Schaalbaarheid
- Beperken complexiteit
- Verkorten time-to-market
- Autonomie van ontwikkelteams
Omdat autonome teams zelf verantwoordelijk zijn voor het beheer en ontwikkeling van een Microservice wordt de transparantie vergroot en dat werkt motiverend. De grootste investeringen vinden vooral in het begin plaats wanneer er zwaar geïnvesteerd moet worden in Scaffolding, Continuous Delivery, blauwdrukken, teamvorming en architectuur-principes.