Versiebeheer
Versiebeheer
Versie Verandering Datum Door
0.01 Document aanmaken 17-02-2020 Teun
0.02 Template toevoegen van Verzuimsignaal 6-4-2020 Teun 0.1 Toevoegen van:
● versiebeheer;
● mogelijke hoofdstukken.
6-4-2020 Teun
0.2 Verder werken aan het onderzoeksverslag 19-5-2020 Teun 0.3 Ontwerp aan scriptie toevoegen. 28-5-2020 Teun
0.4 Implementatie 29-5-2020 Teun
0.5 ● Testen toevoegen.
● Puntjes op de i zetten. 1-6-2020 Teun
0.6 ● Context en probleem opnieuw beschrijven.
● Hoofdstuk 5. Onderzoek herschrijven. ● Toekomstige architectuur toepassen.
31-8-2020 Teun
0.7 ● Paginaindeling veranderen.
● Spellingscontrole toepassen. 4-10-2020 Teun 1.0 ● Hoofdstuk 6. Ontwerp in contrast
brengen met het onderzoek.
● Hoofdstuk 7. Implementatie beter in contrast brengen met het ontwerp en het onderzoek.
● Gedetailleerde feedback verwerken. ● Spellingscontrole toepassen.
26-10-2020 Teun
Voorwoord
Tijdens deze afstudeerperiode heb ik veel geleerd en heb ik mogen werken aan een leuke opdracht. Hiervoor wil ik mijn technisch begeleider Gerwin Boode en mijn bedrijfsbegeleider Simon Paarhuis bedanken. Ook wil ik hen bedanken voor de goede begeleiding tijdens deze bijzondere coronatijd. Verder wil ik mijn dank uitspreken aan mijn collega’s van Verzuimsignaal, omdat ze altijd tijd voor mij vrij konden maken.
Samenvatting
Afgelopen februari is de onderzoeker gestart met zijn afstudeerstage bij
Verzuimsignaal. Hier kreeg de onderzoeker de opdracht om erachter te komen wat de beste manier is om de monolithische applicatie van Verzuimsignaal om te zetten naar een microservice-architectuur.
Om erachter te komen hoe een monolithisch applicatie omgezet kan worden naar een microservice, moest eerst een onderzoek worden uitgevoerd. Hierbij is bestudeerd wat een microservice inhoudt, waaruit een microservice bestaat, wat de voor- en nadelen zijn en hoe een microservice kan worden uitgerold in de cloud.
Deze vragen waren het startpunt van het onderzoek. Inmiddels is gebleken dat het niet mogelijk is een microservice vast te leggen op één punt, maar dat een
microservice bestaat uit vele verschillende patterns en componenten. Hierdoor is het afhankelijk van de wensen van de organisatie welke patterns en componenten er worden gebruikt in de microservice.
Verzuimsignaal wil een microservice voor het registreren van verzuim met twee
verschillende patterns: CQRS en Event-sourcing. Aan de hand van deze twee patterns zijn nog meer patterns gevonden die handig zijn voor de microservice. Vervolgens is onderzocht welke pub/sub-systemen goed werken voor eventsourcing. Uit dit onderzoek leek Kafka het beste systeem en is hiervoor een Proof of Concept (PoC) opgesteld. Helaas werkte Kafka niet, omdat er geen goede PHP-extensie was voor Kafka. Hierna is gekeken naar Redis als PoC en is een kleine setup gemaakt in Laravel. Deze PoC slaagde wel en is opgenomen in de ontwerpfase.
Doordat er in de onderzoeksfase al een PoC is opgesteld, was het eenvoudig om de vereisten en de feedback van de technische begeleider mee te nemen in het ontwerp. Hierdoor is de implementatiefase snel gegaan en waren er weinig verbeterpunten.
Het advies is dan ook als volgt: het is een goed idee om de grote applicatie op te delen in kleine microservice. Dit biedt de mogelijkheid om de processen te scheiden van elkaar en de resources neer te zetten waar dit nodig is. Daarnaast is het hierdoor mogelijk om de keuze voor het huidige systeem opnieuw in te zien en te
implementeren in de microservice.
Inhoudsopgave
Voorwoord 3 Samenvatting 4 1. Introductie 7 2. Achtergrond 8 2.1. Verzuimsignaal 8 2.2. Microservices 8 3. De opdracht 9 3.1. Probleemstelling 9 3.2. Doelstelling 10 3.3. Projectgrenzen 10 3.4. Resultaat 11 3.4.1. Onderzoeksrapport 11 3.4.2. Ontwerp 11 3.4.3. Prototype 11 4. Uitvoering 13 4.1. Onderzoek 13 4.2. Ontwerp 13 4.3. Realisatie 13 5. Onderzoek 14 5.1. Deelvragen 14
5.2. Wat zijn de hoofdredenen van Verzuimsignaal om over te stappen naar een
microservice-architectuur? 16
5.3. Waaruit bestaat een microservice-architectuur? 18 5.3.1. De verschillende patterns in een Microservice Architecture 20
5.4. Datamanagement 21 5.5. Pub/sub-systemen 24 5.5.1. Apache Kafka 24 5.5.2. RabbitMQ 25 5.5.3. Redis 26 5.5.4. Cloud Pub/Sub 27 5.5.5. Conclusie 28
5.6. Hoe kan de microservices-oplossing in de cloud worden uitgerold? 29 5.6.1. Multiple Service Instances per Host Pattern 29
5.6.2. Service Instance per Host Pattern 29
5.6.3. Service Instance per Virtual Machine 30
5.6.5. Conclusie 30 5.7. Wat zijn de voor- en nadelen voor Verzuimsignaal om over te stappen naar
een microservice-architectuur? 31
5.8. Hoe zou een microservice-architectuur eruitzien in de huidige omgeving van
Verzuimsignaal? 32 5.8.1. Microservice-architectuurplaat 34 5.9. Proof of concept 36 5.10. Conclusie onderzoek 37 6. Ontwerp 40 6.1 Archimate-componentdiagram 40 7. Implementatie 43
7.2. Het opzetten van de microservice-omgeving 43
7.3. Het opzetten van de API 44
7.4. De verschillende componenten in de service 45
7.5 De werking de microservice 47 7.6. Testen 48 7.7. Deployment in Kubernetes 49 8. Conclusie en aanbevelingen 50 9. Literatuurlijst 51 10. Bijlagen 56 Interviews 56
Matthijs Schonewile (Front-end developer): 56
Frank Leijzer (Tester van Verzuimsignaal) 57
Gillian Lo Wong (Back-end developer) 58
Marjolein Tibbe (Product owner) 59
Uitgevoerde testen 60
Reflectie 62
Figuren 63
Tabellen 63
1. Introductie
Vanaf 10 februari 2020 tot 10 juli 2020 en van 31 augustus tot 13 november heeft Teun Heurman een afstudeertraject gevolgd ter afronding van de opleiding HBO-ICT
Software Engineering. Dit is gedaan bij het bedrijf Verzuimsignaal. Dit document geeft het traject van de afstudeerperiode weer.
In dit document wordt beschreven welk probleem Verzuimsignaal ondervindt en hoe dit probleem wordt aangepakt. Hierna worden het uitgevoerde onderzoek en de bijbehorende resultaten beschreven. Verder worden de ontwerpfase en realisatiefase beschreven.
2. Achtergrond
In dit hoofdstuk wordt uitgelegd wat Verzuimsignaal doet. Ook wordt kort toegelicht wat microservices zijn. Hierdoor krijgt de lezer meer achtergrondinformatie over het onderwerp van deze scriptie en kan deze het verhaal beter begrijpen.
2.1. Verzuimsignaal
Verzuimsignaal biedt een online platform voor werkgevers, arbodiensten en bedrijfsartsen om samen te werken aan het verzuimproces. Een werkgever kan inzicht krijgen in het verzuim van zijn medewerkers. De arbodienst is niet alleen verzuimcoach, maar is ook verantwoordelijk voor het registeren van het
verzuimproces. Verzuimsignaal helpt de arbodienst hierbij, door eenvoudige registratie en automatische processen bij het registreren van verzuim. Voor de bedrijfsarts is het voornamelijk van belang dat de medische gegevens veilig en volgens de eisen van de wet worden bewaard en afgeschermd. Hiervoor biedt Verzuimsignaal de mogelijkheid.
De visie van Verzuimsignaal is dat de werknemer centraal moet staan. Verzuimsignaal wil werknemers veilig, gezond en duurzaam inzetbaar houden, door samen met
klanten te werken aan gebruiksvriendelijke, krachtige en flexibele onlinesoftware. Hierdoor zijn de online apps goed te gebruiken voor verzuimbegeleiding en een goede tool voor verzuimpreventie. Daarbij gelooft Verzuimsignaal sterk in de kracht van eenvoud, connectiviteit en data.
2.2. Microservices
Een microservice is een klein gedeelte van de applicatie dat zelfstandig werkt zonder dat het erg afhankelijk is van de rest van de applicatie. Hierbij beheert een microservice een gedeelte van de functionaliteiten van een applicatie. Het principe van microservices wordt vaak gebruikt om grote monolithische applicaties op te
splitsen in kleine logische applicaties (zie Figuur 1). Het voordeel van microservices is dat iedere microservice individueel werkt en dus ook individueel ontwikkeld kan worden. Dit maakt het voor veel bedrijven interessant om te gebruiken. In hoofdstuk 5.3 wordt verder beschreven wat microservices zijn.
Figuur 1: Microservice-architectuur.
3. De opdracht
Verzuimsignaal is al sinds 2008 bezig met het ontwikkelen van zijn applicatie. In die tijd is de applicatie gegroeid en heeft deze allerlei nieuwe features en
maatwerkoplossingen voor verschillende klanten. De applicatie is hierdoor uitgegroeid tot een grote monoliet. Alleen al de verzuimapplicatie bestaat uit meer dan 70.000 bestanden. Een instantie van de database bestaat uit meer dan 550 verschillende tabellen met net iets minder dan 5000 kolommen in totaal. Doordat de applicatie nu zo groot is, ontstaan er steeds vaker complicaties bij het ontwikkelen van de
applicatie. De grote klanten die gebruikmaken van Verzuimsignaal ondervinden dat de applicatie steeds vaker traag is of zelfs vastloopt.
3.1. Probleemstelling
Doordat de applicatie van Verzuimsignaal zo groot is, ontstaat er een aantal
problemen. Zo kan het bij grote klanten soms tot wel 5 minuten duren voordat een overzicht is geladen. Dit komt doordat het overzicht nog gegenereerd moet worden en alle benodigde data niet in één tabel staan. In sommige gevallen moeten deze data eerst nog berekend worden. Zo kan het zijn dat er voor één persoon tussen de 180 en 400 query’s worden uitgevoerd. Het probleem is dat er geen goede datastructuur is voor sommige overzichten. Verticaal opschalen is geen oplossing meer, omdat het cluster al op de limiet zit. Dit is ook een van de redenen dat het niet verstandig is om verticaal te gaan opschalen. Het probleem ligt in de applicatie en het is niet op te lossen door de server te upgraden. Daarnaast ondervindt het ontwikkelteam problemen bij het oppakken van issues. Zo is het vaak niet duidelijk waar een probleem zich bevindt en moet eerst een dag of een halve dag onderzoek worden gedaan. Wanneer het probleem verholpen is, is het lastig om te testen of er niet een ander onderdeel van de applicatie is stukgegaan. Dit komt doordat veel stukken code vaak zijn aangepast en lastig te lezen zijn. Verder wordt geen gebruikgemaakt van automatisch testen, dus moeten ontwikkelaars en testers dit met de hand doen.
NR. Probleemomschrijving
P1 Bugs zijn moeilijk te traceren door de omvang van het systeem, waardoor het veel tijd kost om de applicatie te onderhouden.
P2 Bugs kunnen impact hebben op de hele applicatie, waardoor de hele bedrijfsvoering van de klanten van Verzuimsignaal stil komt te liggen.
P3 Door de intreding van GDPR moeten klantdata logisch worden gescheiden voor het doel waarvoor ze verzameld zijn. Er werken verschillende rollen in het systeem. Deze rollen hebben allemaal hun eigen informatiebehoefte en deze informatie mag niet inzichtelijk zijn voor de andere rollen. Door de
huidige opzet zit alle informatie in één applicatie/database, waardoor klantdata niet gescheiden kunnen worden.
P4 Fundamentele aanpassingen kosten veel tijd omdat veel applicatiecomponenten aangepast moeten worden.
P5 Performance van de applicatie is moeilijk te waarborgen, omdat alle interacties met de database in de complete dataset moeten plaatsvinden. Tabel 1: Probleemomschrijving.
3.2. Doelstelling
Het doel van dit project is om een prototype microservice te maken die past bij de situatie van Verzuimsignaal. Hierbij wordt het prototype gebouwd met de
probleemstellingen in gedachte, zodat deze worden opgelost of verholpen. Het prototype is geen vervanging voor het huidige systeem, maar een mogelijke uitbreiding.
Een gebruiker zal verzuim kunnen registeren via de microservice. Daarnaast zal de gebruiker een overzicht kunnen ophalen van:
● alle verzuimmeldingen;
● de samengestelde verzuimmeldingen; ● de verzuimmeldingen per werknemer.
Voordat de afstudeerperiode begon, zijn de randvoorwaarden van het prototype besproken. Dit prototype zal gebruikmaken van een microservice-architectuur.
3.3. Projectgrenzen
Om het project af te kunnen bakenen, is een aantal projectgrenzen opgesteld. Deze projectgrenzen zijn belangrijk, omdat ze ervoor zorgen dat het project behandelbaar blijft in de afstudeerperiode. Deze projectgrenzen zijn opgesteld in overleg met de bedrijfsbegeleiders.
● Het prototype hoeft niet volledig geïmplementeerd te worden in de huidige applicatie, maar de huidige applicatie moet wel kunnen communiceren met het prototype.
● Het prototype zal op zichzelf werken zonder te veel afhankelijkheden van het huidige systeem.
● Het prototype wordt ontwikkeld in PHP vanwege de kennis van de ontwikkelteams binnen Verzuimsignaal.
● De afstudeerperiode begint op maandag 10 februari 2020 en eindigt op vrijdag 13 november 2020.
3.4. Resultaat
Tijdens de afstudeerperiode wordt gewerkt aan een aantal afstudeerproducten. Dit zijn onder andere: het onderzoeksrapport, een ontwerp en een prototype. In dit hoofdstuk worden deze drie producten toegelicht.
3.4.1. Onderzoeksrapport
In het onderzoeksrapport wordt de volgende hoofdvraag besproken:
Hoe kan Verzuimsignaal zijn monolithische architectuur omzetten naar microservices?
Deze hoofdvraag wordt opgedeeld in de volgende deelvragen:
● Wat zijn de hoofdredenen van Verzuimsignaal om over te stappen naar een microservice-architectuur?
● Waaruit bestaat een microservice-architectuur en wat zijn de voor- en nadelen hiervan?
● Wat zijn de voor- en nadelen voor Verzuimsignaal om over te stappen naar een microservice-architectuur?
● Hoe kan de microservice-oplossing in de cloud worden uitgerold?
● Hoe zou een microservice-architectuur eruitzien in de huidige omgeving van Verzuimsignaal?
Om deze deelvragen te kunnen beantwoorden, wordt gebruikgemaakt van de
volgende onderzoeksmethoden: interview (HBO-I, 2018), literature study (HBO-I, 2018), best, good and bad practices (HBO-I, 2018), available product analysis (HBO-I, 2018) en pitch (HBO-I, 2018).
3.4.2. Ontwerp
Om een beter idee te krijgen van hoe het prototype eruit gaat zien en hoe het straks gaat functioneren, wordt een aantal ontwerpen gemaakt, namelijk: een
systeemarchitecture om een beter beeld te krijgen van de relatie tussen de
verschillende componenten, een ERD-diagram om de databasestructuur in beeld te krijgen om alle verschillende events en projectie in kaart te brengen en om weer te geven hoe de database wordt benaderd, een sequence-diagram om het gedrag van het systeem in kaart te brengen en een klassendiagram om de structuur van het systeem in kaart te brengen.
Om de verschillende keuzes die voor het ontwerp worden gemaakt vast te leggen, wordt een technisch dossier opgesteld. In dit dossier komen alle ontwerpen terug met daarbij de keuzes die zijn gemaakt en waarom deze keuzes zijn gemaakt.
3.4.3. Prototype
Bij het maken van het prototype moet rekening worden gehouden met de criteria die zijn benoemd in Hoofdstuk 2. Veel van de technologieën, zoals het
pub/sub-messaging system, moeten nog onderzocht worden om te bepalen of dit wel de beste technologieën zijn voor de huidige problemen. Door een component test uit
te voeren, wordt aangetoond dat de microservice ook zonder het huidige systeem kan functioneren. Door het opzetten van een unittest moeten toekomstige bugs worden voorkomen.
4. Procesaanpak
Om een beter inzicht te krijgen in de beste aanpak voor het afstudeeronderzoek, is gebruikgemaakt van de Methoden Toolkit HBO-I (HBO-I, 2018). Hierin wordt verwezen naar de verschillende methoden per projectfase. Voor het gehele traject is er gebruik gemaakt van Scrum en het Watervalmethode.
4.1. Onderzoek
In dit onderzoek wordt met veel nieuwe technologieën gewerkt, waardoor ervoor is gekozen om eerst onderzoek te doen naar deze technologieën. Hiervoor wordt gekeken naar de literature study (HBO-I, 2018), best, good and bad practices (HBO-I, 2018) en available product analysis (HBO-I, 2018). Om goed beeld te krijgen van het geheel, wordt een interview (HBO-I, 2018) afgenomen met de business coordinator. Hierdoor wordt duidelijk welke services moeten worden gemaakt. Wanneer dit
allemaal in kaart is gebracht, wordt een pitch (HBO-I, 2018) gehouden om feedback te kunnen ontvangen.
4.2. Ontwerp
Bij het ontwerpen van de software-architectuur wordt eerst een literature study (HBO-I, 2018) uitgevoerd om te analyseren hoe een microservice meestal wordt ontworpen. Hierna vindt een IT-architecture sketching (HBO-I, 2018) plaats en vervolgens een decomposition (HBO-I, 2018). Daarnaast wordt een design pattern research (HBO-I, 2018) uitgevoerd om bekende structure toe te passen op het
ontwerp om de kwaliteit van het ontwerp te verbeteren. Wanneer het ontwerp af is, wordt het gepitcht om hierop feedback te kunnen krijgen.
4.3. Realisatie
Bij het realiseren van het ontwerp wordt gebruikgemaakt van literature study (HBO-I, 2018). Problemen worden opgelost aan de hand van community research (HBO-I, 2018). Om een aantal problemen in de huidige situatie te testen zodra het systeem is verbeterd, wordt gebruikgemaakt van een component test (HBO-I, 2018) en een unittest (HBO-I, 2018)
5. Onderzoek
Het doel van dit onderzoek is om te achterhalen: Hoe kan Verzuimsignaal zijn monolithische architectuur omzetten naar microservices? Dit onderzoek is nodig omdat er binnen het bedrijf nog geen onderzoek is gedaan naar de best passende oplossing voor de situatie. Het einddoel van dit onderzoek is om inzichtelijk te maken hoe een deel van de applicatie kan worden omgezet naar microservices. Hierbij is het van belang te benoemen welke mogelijke technologieën er zijn en te bepalen welke technologie het best past bij de situatie van Verzuimsignaal.
Om het onderzoek zo goed mogelijk uit te kunnen voeren, zijn deelvragen opgesteld. In paragraaf 5.1 komen deze deelvragen aan de orde. Besproken wordt waarom deze deelvragen zijn gekozen en met welke onderzoeksmethoden de deelvragen zijn beantwoord. Vervolgens worden de opzet en de uitvoering van het onderzoek toegelicht. De gevonden resultaten worden besproken en een conclusie wordt gegeven.
5.1. Deelvragen
Wat zijn de hoofdredenen van Verzuimsignaal om over te stappen naar een microservice-architectuur?
Deze deelvraag is gekozen om meer inzicht te krijgen in de grondlegging van het probleem. Deze deelvraag is beantwoord door middel van een interview met Verzuimsignaal (hbo-i, 2015). Tijdens dit interview zullen meerdere kanten van de onderneming aan bod komen, maar de focus ligt op de ontwikkelaars. Na het
afnemen van het interview is de verwachting dat geconstateerd kan worden wat de impact kan zijn.
Waaruit bestaat een microservice-architectuur en wat zijn de voor- en nadelen hiervan?
Deze deelvraag is gekozen om meer inzicht te krijgen in wat
microservice-architectuur is, uit welke componenten het bestaat en wat de voor- en nadelen ervan zijn. De beste manier om dit te onderzoeken, is door middel van een literature study (HBO-i, 2019). Hierna volgt een available product analysis (HBO-i, 2018) om erachter te komen welke producten er zijn voor de verschillende
componenten. Als laatste zal een best, good and bad practices (HBO-i, 2018) worden uitgevoerd om de voor- en nadelen van de verschillende producten aan te tonen.
Wat zijn de voor- en nadelen voor Verzuimsignaal om over te stappen naar een microservice-architectuur?
Bij deze deelvraag wordt in kaart gebracht wat de voor- en nadelen zijn wanneer Verzuimsignaal overgaat naar een microservice-architectuur. Om hier antwoord op te krijgen, moet eerst de vorige deelvraag beantwoord zijn. Hieruit kan worden herleid wat de voor- en nadelen zijn van een microservice-architectuur. Hierna kan door middel van een expertinterview (HBO-i, 2019) worden vastgelegd wat de voor- en nadelen zijn voor Verzuimsignaal.
Hoe kan de microservice-architectuur in de cloud worden uitgerold?
Met behulp van deze deelvraag is het mogelijk om te kijken naar hoe de applicatie gedeployed kan worden. Dit kan grote gevolgen hebben voor het ontwerp van het systeem. Het doel van deze deelvraag is om duidelijkheid te krijgen over de
mogelijkheden die er momenteel in de cloud zijn en hoe daar naartoe gewerkt kan worden. Hierbij wordt vooral gebruikgemaakt van available product analysis (HBO-i, 2018).
Hoe zou een microservice-architectuur eruitzien in de huidige omgeving van Verzuimsignaal?
Deze deelvraag is gesteld om meer inzicht te krijgen in de manier waarop een mogelijke microservice-architectuur eruit kan komen te zien. Hierbij wordt een ontwerp gemaakt dat laat zien welke componenten gebruikt kunnen worden.
5.2. Wat zijn de hoofdredenen van Verzuimsignaal
om over te stappen naar een
microservice-architectuur?
Om deze deelvraag te beantwoorden, is een aantal vragen opgesteld voor een interview. Deze vragen zijn vooral bedoeld om te bepalen welke problemen de medewerkers van Verzuimsignaal ervaren. De vragen van dit interview staan in de bijlagen hoofdstuk interviews. Het interview is afgenomen bij vier personen: één
front-end developer, een back-end developer, een tester en een product-owner. Deze vier personen representeren de groep die werkt aan de applicatie.
Resultaten
Het meest opvallende probleem dat werd aangegeven in de interviews, is dat de applicatie erg groot is. Dit maakt de applicatie complex en instabiel. Zowel de front-end developer als de back-end developer gaven aan dat het hierdoor lastig is om aanpassingen te doen. Wanneer ze bijvoorbeeld functie A aanpassen, kan het zijn dat functie B hierdoor niet meer werkt. Ze kunnen niet één onderdeel van de
applicatie aanpassen zonder dat het andere delen raakt. Hierdoor is het lastig voor de developers om eenvoudige functies snel door te voeren. Iedere aanpassing die ze doen heeft impact op de applicatie en soms op plekken die ze niet verwachten. Doordat de problemen zich overal kunnen voordoen, moet de applicatie voor het vrijgeven van een functie grondig worden getest op alle functionaliteiten. Dit kost veel tijd; met name doordat functionaliteiten meestal niet automatisch worden getest. Bij de functionaliteiten die wel automatisch getest worden, speelt ook een aantal
problemen. Hierbij werd benoemd dat de testen te lang zijn en dat de test stopt zodra er een fout optreedt, waardoor de test niet kon worden vervolgd. Dit probleem heeft een aantal oorzaken:
● De code is sterk verouderd.
● De code is in het verleden vaak gedupliceerd voor een functie die hetzelfde leek te doen.
● Alle tabellen in de database zijn met elkaar gekoppeld en er zijn in het verleden onlogische keuzes gemaakt voor sommige velden en tabellen. Hierdoor is het lastig om de benodigde data naar boven te halen. Hiervoor wordt vaak gebruikgemaakt van een groot aantal inner joins en subqueries. ● Alles zit in één grote bak (php/html/css/js/db).
● De problemen werden snel opgelost met een hot-fix in plaats van te onderzoeken waar het probleem zich echt afspeelt.
Conclusie
Na het afnemen van de interviews is duidelijk geworden wat de hoofdredenen zijn van de medewerkers van Verzuimsignaal om over te stappen naar een
complex. Een microservice zou hiervoor een oplossing kunnen bieden, omdat de huidige applicatie dan wordt opgedeeld in logische services. Hierbij moet nog wel worden onderzocht welke onderdelen van een microservice-architectuur het beste passen bij Verzuimsignaal.
5.3. Waaruit bestaat een microservice-architectuur?
Om deze onderzoeksvraag te kunnen beantwoorden, moet eerst in beeld worden gebracht wat een microservice-architectuur is. Dit wordt toegelicht met een kort voorbeeld. Hierna wordt uitgelegd waaruit een microservice bestaat en wat de voor- en nadelen hiervan zijn.
Voorafgaand aan dit onderzoek was niet veel bekend over wat microservices zijn en waarvoor ze gebruikt kunnen worden. Het principe van microservices (Richardson, 2019) is simpel: de applicatie wordt opgeknipt in kleinere applicaties. Deze kleine applicaties, ook wel services genoemd, hebben ieder één doel. Door dit principe ontstaan veel kleine services die allemaal hun eigen doel hebben.
Figuur 2: Voorbeeld microservice-architectuur.
Figuur 2 is een voorbeeld van een microservice-architectuur. Hierbij is een e-commerce-applicatie (Richardson, Pattern: Microservice Architecture, 2019) opgedeeld in verschillende componenten. In dit voorbeeld is er sprake van een Account Service. Deze service zal alle functionaliteiten die bij een account horen uitvoeren. Voorbeelden van deze functionaliteiten zijn het aanmaken van een
account, het updaten van een account of het weergeven van een account. Om deze functionaliteiten uit te kunnen voeren, moet de service de accountgegevens opslaan. Dit gebeurt in de Account DB. In deze database staat alleen accountgerelateerde informatie. De Account Service is de enige service die hier direct toegang toe heeft. Wanneer een andere service of component informatie wil hebben over een account,
kunnen deze dit opvragen via de REST API van de Account Service. Hierdoor heeft de Account Service altijd de controle over de data.
De voor- en nadelen van een microservice-architectuur
Een voordeel van microservice-architectuur is dat de applicatie wordt opgedeeld in kleinere applicaties. Hierdoor kunnen ook de performances van een microservice worden gemeten en opgeschaald waar dit nodig is. Daarnaast zijn de microservices niet afhankelijk van één taal. De ene microservice kan bijvoorbeeld geschreven zijn in Java en de andere in PHP. Het voordeel hiervan is dat ieder team aan zijn eigen microservice kan werken met zijn eigen tools. Een ander voordeel is dat bugs in een microservice in theorie sneller te vinden en op te lossen zijn. Dit komt doordat
microservices gebouwd worden om onafhankelijk van elkaar te zijn. Al deze voordelen lijken goede oplossingen voor de problemen van Verzuimsignaal:
● Bugs zijn makkelijker op te sporen [P1].
● Bugs hebben alleen impact op hun eigen omgeving [P2].
● Fundamentele aanpassingen zijn beter door te voeren doordat de microservices individueel van elkaar werken [P4].
● De performance van een microservice kan worden gemeten en gewaarborgd door de juiste tooling of services [P5].
Er zitten ook nadelen aan microservices. Een van de nadelen van een
microservice-architectuur is de complexiteit. Kleine microservices zijn sneller te begrijpen en minder complex dan dezelfde functies in een monoliet, maar door gebruik te maken van de microservice-architectuur ontstaan veel bewegende delen. Bewegende onderdelen zijn bijvoorbeeld messaging systemen of databases. Door al deze bewegende onderdelen die aan elkaar zijn gekoppeld, wordt het systeem complex. Een ander nadeel is dat het lastig is om te beslissen welke microservices waarvoor verantwoordelijk zijn en waarvoor niet. Dit zijn technische keuzes die moeten worden afgestemd met de domeinexperts.
bronnen:
(Paans, 2017), (Varghese, 2017), (Wrong Ways of Defining Service Boundaries, 2017)
5.3.1. De verschillende patterns in een Microservice Architecture
Bij een microservice kunnen veel verschillende keuzes gemaakt worden op het gebied van patterns. Zo worden in het voorbeeld van Figuur 2 al vijf verschillende patterns gebruikt, namelijk: Microservice Architecture, Database per Service, API Composition, API gateway en Client-side UI composition. Deze patterns hebben allemaal hun eigen voor- en nadelen wanneer ze gebruikt worden in een applicatie. Naast deze vijf patterns is er nog een lijst met verschillende patterns (Richardson, Pattern: Microservice Architecture, 2019) die bij een microservice-architectuur gebruikt kunnen worden, zie Figuur 3. Er zijn veel verschillende patterns die allemaal een oplossing geven voor een probleem. De architect moet bepalen welke problemen er zijn en welke patterns kunnen daarbij kunnen helpen. In dit onderzoek wordt gekeken naar de patterns in deployment [5.6] en datamanagement [5.4].
Figuur 3: Verschillende patterns.
5.4. Datamanagement
In dit hoofdstuk wordt gekeken naar de verschillende patterns die onder
datamanagement vallen. Hierbij wordt de functie van de verschillende patterns toegelicht en wordt bepaald waarvoor ze gebruikt kunnen worden.
Database per service
Deze pattern bepaalt dat iedere service in de microservice-architectuur zijn eigen database krijgt. Hierbij mogen de data alleen worden aangepast door deze service en worden opgehaald door de API van deze service. De voordelen van deze pattern zijn dat veranderingen in de database van een service geen impact hebben op andere services en dat iedere service zijn eigen type database kan hebben. Er zijn ook nadelen bij het gebruik van deze pattern. Het is bijvoorbeeld lastig om query’s uit te voeren die data joinen. Acties die gegevens nodig hebben uit verschillende services zijn complexer geworden en verschillende services hebben verschillende typen data opslag nodig, waardoor de complexiteit hoger wordt.
Shared database pattern
Met deze pattern maken alle services gebruik van één database. Hierbij heeft iedere service wel zijn eigen table in de database en mag deze ook alleen zijn data
bewerken. Hierbij kan de programmeur gebruikmaken van ACID om data constant te houden. Daarnaast is het gebruik van één database simpeler. De nadelen hiervan zijn dat alle services gebruik kunnen maken van alle tables, waardoor ander services soms geblokkeerd kunnen worden. Verschillende services hebben soms verschillende data storage requirements waarmee ze beter kunnen werken. Hierbij wordt nu een standaard gebruikt.
Saga
Saga kan worden gebruikt wanneer is gekozen voor een ‘Database per
service’-pattern en is bedoeld voor data consistency. Hierbij gaat het om het forceren van business rules. Een voorbeeld is wanneer een klant geen bestelling doen als hij een limiet heeft bereikt. Dit wordt gedaan door een lijst met verrichtingen uit te voeren over de verschillende databases. Wanneer een verrichting is afgerond, begint de volgende door middel van een trigger of een event, maar wanneer een verrichting één van de business rules overtreedt, worden de vorige verrichtingen ook
teruggedraaid. Een nadeel hiervan is dat het complex is, doordat de developer de verrichtingen moet schrijven die moeten gebeuren op het moment dat een verrichting niet is toegestaan. Een ander nadeel is dat Saga gebruikmaakt van message/events.
API Composition
Een van de problemen van Database per service is dat het niet mogelijk is om query's uit te voeren die data joinen. De API Composition is een service die boven alle andere services hangt en in-memory join-queries kan uitvoeren. Een voordeel hiervan is dat queries uitvoeren makkelijker is. Een nadeel is dat het resultaat in-memory wordt opgeslagen en voor grote datasets is dit een inefficiënte wijze om het geheugen te gebruiken.
Domain events
Domain events bepalen wanneer een service een event moet publiceren. Hierbij is een service ontworpen met domain-driven design (DDD). De service is gebouwd op business logic. Hierdoor heeft de service een aantal grondregels die bepalen hoe de service reageert op bepaalde input en weet hij ook wanneer hij een event moet publiceren.
Event sourcing
Event sourcing is het gebruikmaken van events om te communiceren dat er een verandering is. Dit gaat over de manier waarop een log wordt gemaakt waarin verschillende gebeurtenissen worden opgeslagen. Voorbeelden van events zijn ‘nieuwe klant’, ‘klantgegevens zijn gewijzigd’ en ‘klant is verwijderd’. Al deze events worden in volgorde opgeslagen, zodat ze later kunnen worden afgespeeld om de huidige situatie te krijgen. Een nadeel hiervan is dat het lastig is om de data te querien.
CQRS
Een veelgebruikt pattern met microservice is CQRS (CQRS, 2011). CQRS staat voor Command Query Responsibility Segregation en wordt vaak gebruikt in combinatie met Database per service en Event sourcing. CQRS houdt in dat het schrijven (command) en het lezen (query) van elkaar gescheiden worden gehouden. Een voorbeeld hiervan is een applicatie met twee databases. De eerste database is de read-database en de andere is een write-database. Hierbij is het mogelijk om de read-database volledig te optimaliseren met indexen, zonder dat de write-database er last van heeft. Het nadeel van deze opzet is dat de write-database gesynchroniseerd moet worden met de read-database. Een manier om de write-database te synchroniseren met de read-database, is door de events die zijn geüpdatet te publiceren naar de read-database. Deze actie gebeurt in één transactie.
Doordat de read en write van elkaar gescheiden zijn, kan worden gekeken naar de performance van de twee databases. Wanneer er 10.000 queries binnenkomen en maar 200 commands, is het verstandig om meer recourse te geven aan de
read-database dan aan de write-database. Voordelen:
● Door CQRS is het mogelijk om de write en read onafhankelijk van elkaar op te schalen.
● De read-zijde kan worden geoptimaliseerd door het gebruik van schema's en bij de write-zijde is het mogelijk om gebruik te maken van schema’s voor het optimaliseren van de updates. Bij Event sourcing zal dit geen effect hebben, omdat de database immutable is en de data niet wordt geüpdatet.
● Het is gemakkelijker om de juiste schrijfrechten te geven.
● Door het scheiden van de queries en de commands zijn de modellen beter te onderhouden en meer flexibel.
Door het opslaan van materialized view in de read-database kunnen complexe joins worden voorkomen.
Conclusie
Nu duidelijk is welke patterns er zijn bij datamanagement in een
microservice-architectuur, kan worden bepaald welk pattern het best past bij de situatie van Verzuimsignaal. Geadviseerd wordt om te kiezen voor het pattern Database per service. Dit pattern zal helpen om de data te scheiden [P3] en om de performance beter te waarborgen [P5]. Daarnaast wordt de applicatie gebouwd met Domain events, Event sourcing en CQRS in gedachte. Door gebruik te maken van Domain events blijven data consistent, met inachtneming van de gestelde
businessrules. Om deze data consistent te houden bij alle services, wordt
gebruikgemaakt van Event sourcing. Hierdoor kan iedere service de benodigde data ontvangen. Voor het realiseren van een microservice-architectuur die gebruikmaakt van Event sourcing is een pub/sub-systeem nodig. Dit wordt toegelicht in paragraaf 5.5. Daarnaast is het advies om CQRS toe te passen in het systeem. Dit zal helpen bij het doorvoeren van fundamentele aanpassing [P4]. Hierdoor kan gebruik worden gemaakt van views in plaats van het uitvoeren van queries om de juiste data te krijgen. Ook kan dit helpen bij de Performance van de applicatie, omdat de dataset is opgedeeld in verschillende views, waardoor weinig queries uitgevoerd moeten worden [P5]. Bronnen: (Richards, 2018)
5.5. Pub/sub-systemen
Voor dit onderzoek is bekeken welke pub/sub-messagingsystemen er zijn en welke relevant zijn. Op deze wijze wordt duidelijk welke technieken de huidige
pub/sub-systemen hebben en wat het beste past bij de gewenste situatie. Tijdens dit onderzoek zijn een aantal pub/sub-systemen naar voren gekomen: RabbitMQ, Apache Kafka, Google cloud sub/pub en Redis. Deze vier pub/sub-systemen zijn geselecteerd omdat verschillende artikelen positief over deze systemen waren.
5.5.1. Apache Kafka
Over Kafka is veel geschreven, waardoor er veel over dit systeem te vinden is (Sookocheff, 2015). Kafka is een pub/sub-messagingsysteem dat gericht is op eventsourcing. Binnen Kafka is er een producer die een bericht naar een topic
verstuurd. Een topic kan dan nul of meerdere consumers hebben die subscribed zijn. Wanneer het bericht ontvangen is in de topic, krijgt het bericht een ID. Dit ID wordt later gebruikt door de consumers om de volgorde van de berichten te achterhalen. Hierdoor weet een consumer altijd de volgorde van een reeks berichten en wanneer hij een bericht mist. Wanneer een bericht ontvangen wordt door een broker, wordt het bericht opgeslagen in de betreffende topic. Binnen Kafka zijn topics goed schaalbaar. Dit komt doordat topics kunnen worden opgedeeld in partitions. Deze partitions worden dan toegewezen aan een broker. Van deze broker kunnen meerdere instanties worden gemaakt. Hierbij kan iedere instantie de master zijn van één
bepaalde partition en deze moet er ook voor zorgen dat de data gesynchroniseerd is met de andere brokers. Andere voordelen van Kafka zijn:
● Kafka is getest op een hoog volume van data (jeps, 2014).
● Doordat een topic opgedeeld kan worden in meerdere partities en deze weer verdeeld kunnen worden over meerdere brokers, is het eenvoudiger om een topic op te schalen.
● De berichten die Kafka stuurt zijn klein (maximaal 1MB) en hebben altijd een key, een timestamp en value.
● Kafka maakt gebruik van een ‘dumb broker/smart consumer-model’. Dit houdt in dat de broker niet probeert te achterhalen welke berichten zijn ontvangen door een consumer, maar dat een consumer kan aangeven welke berichten hij nodig heeft.
● Kafka gebruikt disk I/O in plaats van in-memory. Hierdoor is hij trager, maar gebruikt hij minder hardware.
5.5.2. RabbitMQ
In dit onderzoek is gekeken naar een andere optie voor pub/sub-technologie, namelijk RabbitMQ (cloudamqp, 2015). RabbitMQ is een messagebroker die gebruikmaakt van verschillende protocollen. Deze protocollen zijn onder andere: point-to-point,
request/reply en pub-subcommunication. Daarnaast maakt RabbitMQ gebruik van een smart broker en dumb consumer. Dit houdt in dat de broker een bericht ontvangt wanneer een bericht van een producer naar de broker wordt gestuurd. Hierbij kijkt de broker naar het topic waarop het bericht betrekking heeft en kijkt hij welke
consumers dit bericht moeten ontvangen. De broker stuurt het bericht door naar de consumers en houdt in de gaten of het bericht is ontvangen door een consumer. Een voordeel aan deze opzet is dat de consumer ervan uit kan gaan dat hij het bericht ontvangt, ook als de note tijdelijk wegvalt. In dit geval wordt het bericht tijdelijk opgeslagen en zodra de note weer online komt wordt het bericht verstuurd. Een nadeel aan deze opzet is dat een consumer geen eerder bericht kan ontvangen wanneer hij zich later op een topic aanmeldt. Dit komt doordat RabbitMQ de
berichten die ontvangen zijn door de consumers verwijdert. RabbitMQ gaat ervan uit dat iedere consumer zelf voor de verwerking van de berichten zorgt en zijn taak is alleen het afleveren van de berichten.
Aandachtspunten:
● RabbitMQ is eenvoudig schaalbaar. ● High performant queuing system.
● Er zijn drie manieren om de data te versturen (RabbitMQ vs Apache Kafka, 2018):
○ Direct exchange: one to one exchange of topic.
○ Topic exchange: many producers to many consumers. ○ Fanout exchange: one producer many consumers.
● RabbitMQ zorgt ervoor dat het bericht wordt afgeleverd en bekijkt door middel van de broker of de status van het bericht is aangepast.
● Wanneer een gebruiker zich later op een topic aanmeldt, kan hij de berichten die eerder zijn verstuurd niet terughalen.
● RabbitMQ gaat ervan uit dat consumers online zijn.
● De consumers krijgen berichten zodra ze gepubliceerd zijn. De volgorde van berichten maakt niet zoveel uit.
● RabbitMQ gebruikt in-memory (In-memory database, 2019). Dit is zeer snel maar kost veel hardware.
5.5.3. Redis
Er is ook onderzoek gedaan naar Redis (redis, sd). Redis is ontwikkeld door Salcatore Sanfilippo voor een real-time weblog. Tegenwoordig is Redis een datastructurestore en wordt het gebruikt als database, cache en messagebroker. Redis ondersteunt datastructuren zoals strings, hashes, lists, sets, sorted sets met range queries, bitmaps, hyperloglogs, geospatial indexes met radius queries en streams.
Bij dit onderzoek is het met name relevant wat de messagebroker kan (educba, sd). Redis pub/sub bestaat uit twee componenten: de Redis-client en de Redis-server. De Redis-client zorgt ervoor dat de data naar de Redis-server worden gestuurd. De client kan een console zijn, maar kan ook een API zijn in een andere programmeertaal. De Redis-server is verantwoordelijk voor het opslaan van de data in-memory en de server is verantwoordelijk voor all pub/sub-operaties (redis, sd).
Wanneer een publisher een bericht verstuurt, kan hij dit niet direct naar de consumer sturen. Hij stuurt een bericht naar een channel. Hierbij weet de producer niet of er consumers zijn die subscribed zijn op een channel. Consumers zijn subscribed op één of meerdere channels waarin ze geïnteresseerd zijn. Hierdoor krijgen ze alleen de berichten waarin ze geïnteresseerd zijn. Wanneer een consumer zich inschrijft op een channel, weet hij niet of er een producer is of wie de producers zijn.
Redis blinkt uit in een aantal punten, en met name snelheid. Redis maakt gebruik van push-based delivery. Wanneer een bericht binnenkomt, wordt het bericht direct verstuurd naar de consumers. Dit werkt sneller dan de pull-based delivery die Kafka gebruikt. Hierbij vraagt de consumer de berichten op wanneer hij ze nodig heeft. Push-based message heeft ook nadelen. Zo wordt het bericht verwijderd van de service zodra het is verzonden en dan is niet meer te achterhalen waar het bericht is opgeslagen of waar het vandaan kwam. Dit principe maakt Redis snel, maar niet fault-tolerant.
Redis heeft de laatste jaren hard aan de weg getimmerd en dat blijkt ook uit het artikel van Forstner (2019). Hierin wordt besproken hoe met Redis een eventstore opgezet kan worden en hoe tussen de verschillende microservices gecommuniceerd kan worden. Daarnaast wordt verteld dat streaming mogelijk is sinds Redis versie 5.0. In Redis 5.0 kan gebruikgemaakt worden van at-most-once of at-least-once delivery semantics (Narkhede, 2017) en active-active capabilities (Davis, 2018). Wanneer de optie at-least-once delivery semantics aan staat, zal het systeem bij een foutmelding of een time-out een bericht opnieuw versturen. Hierdoor wordt verzekerd dat een bericht altijd wordt verstuurd.
5.5.4. Cloud Pub/Sub
Naar aanleiding van het artikel van Varghese (2017) is ook gekeken naar Cloud Pub/Sub. Cloud Pub/Sub is een onderdeel van het Google-platform. Dit is een groot platform met veel verschillende componenten, maar in dit onderzoek ligt de focus enkel op Cloud Pub/Sub en de mogelijkheden tot eventsourcing. Bij het maken van een opzet voor eventsourcing wordt in de documentatie van Google verwezen naar het gebruik van een Spanner als pub/sub-systeem. Een Spanner bestaat uit een aantal componenten (Google, 2020):
● Poller app, Polls Spanner: converteert het bericht naar het Avro-format en publiceert het naar pub/sub.
● Archiver: ontvangt events wanneer er berichten worden verstuurd naar een pub/sub-topic en schrijft deze events weg naar een globale archive, namelijk de Cloud Storage.
● Bqloader: wordt getriggerd wanneer er berichten naar de Cloud-storage worden geschreven. De Bqloader schrijft de berichten naar de juiste BigQuery table.
● Janitor: leest alle berichten op een vaste snelheid en schrijft de berichten weg naar het globale archive. Hij zal deze berichten dan gecomprimeerd opslaan voor een lange opslagtermijn.
● Replayer: leest alle berichten van de lange opslagtermijn, decomprimeert de berichten en zet ze op een nieuwe pub/sub-stream.
● Materializer app: filtert alle berichten die naar de pub/sub worden geschreven en zet ze op de corresponderende Redis-database, materialized view, voor snelle toegang.
(Google, 2020)
Cloud Pub/Sub is bedoeld voor het opslaan en op een later tijdstip weer gebruiken van data. Het streamen van events kan gebruikt worden voor:
● het ophalen van grote transacties en analytics;
● het afspelen van berichten voor het trainen of testen van andere systemen; ● het terugzetten van data wanneer de data verloren raakt of corrupt wordt; ● het terugkoppelen van de gebeurtenissen voor een rapport of een audit;
● het creëren van een versie van de database voor het testen van een omgeving. Daarnaast is Cloud Pub/Sub een cloud-omgeving en is het niet open-source.
5.5.5. Conclusie
Nadat de verschillende pub/sub-technologieën zijn besproken, is besloten om te adviseren gebruik te maken van Kafka. Kafka maakt gebruik van smart
consumer/dumb broker en hierdoor is het zeker dat de berichten altijd worden ontvangen en in volgorde gezet kunnen worden. Daarnaast is de kans op dataverlies klein, omdat dezelfde partitions ook op andere brokers staan. RabbitMQ en Redis hebben beide het nadeel dat ze de volgorde van de berichten niet kunnen
garanderen. Wel kunnen ze garanderen dat de berichten minimaal één keer worden
5.6. Hoe kan de microservices-oplossing in de cloud
worden uitgerold?
Om deze deelvraag te beantwoorden, moet eerst worden bekeken welke deployments technologieën er zijn voor microservices. Hiervoor is gebruikgemaakt van een blogpost over deploying microservices (Richardson, Choosing a Microservices Deployment Strategy, 2016). In de volgende paragrafen wordt ingegaan op de twee belangrijkste patterns, namelijk: Multiple Service Instances per Host Pattern (Richardson, Pattern: Multiple service instances per host, sd) en Service Instance per Host pattern
(Richardson, Pattern: Single Service Instance per Host, sd)
5.6.1. Multiple Service Instances per Host Pattern
Bij Multiple Service Instances per Host pattern worden groepen gemaakt van services. Deze groepen met services worden gehost op hetzelfde IP-adres. Iedere service heeft hierbij zijn eigen port, maar maakt wel gebruik van dezelfde resources.
Deze pattern heeft een aantal voor- en nadelen. Een voordeel van deze pattern is dat de services minder resources gebruiken. Dit komt doordat alle services gebruik
kunnen maken van hetzelfde OS. Het nadeel van deze pattern is dat de services niet geïsoleerd zijn. Hierdoor kan een service niet individueel geschaald worden. Daarnaast is het lastig om iedere service te monitoren. Wanneer één service veel resources gebruikt, is het lastig om te achterhalen welke service het is. Wanneer achterhaald is welke service veel resources gebruikt, is het niet mogelijk om deze individueel toe te wijzen, maar moet dit voor de hele groep gebeuren.
5.6.2. Service Instance per Host Pattern
Bij Service Instance per Host Pattern wordt iedere service individueel gedeployd. Hierdoor zijn de services geïsoleerd van elkaar. Het voordeel van deze pattern is dat de services goed gemonitord kunnen worden en gemakkelijk op te schalen zijn waar dit nodig is. Daarnaast kan een service geen resources meer gebruiken van andere services, omdat de service geïsoleerd is. Het nadeel van deze pattern is dat het voor de overhead is. Hiermee wordt bedoeld dat voor iedere service een image moet worden gebouwd. Dit kost veel tijd en met een Virtual Machine (VM) duurt dit lang.
Service Instance per Host Pattern kan worden opgedeeld in twee verschillende scenario's. Het eerste scenario is dat gebruik wordt gemaakt van VM’s. Dit wordt ook wel Service Instance per Virtual Machine genoemd (Richardson, Pattern: Service Instance per VM, sd). Bij het tweede scenario wordt gebruikgemaakt van containers. Dit wordt ook wel Service Instance per Container genoemd.
5.6.3. Service Instance per Virtual Machine
Service Instance per Container maakt van iedere service een VM-image. Wanneer een service als VM runt, is deze service compleet geïsoleerd. Hierdoor is deze service goed schaalbaar. Een voorbeeld van Service Instance per Virtual Machine is Netflix. Netflix verpakt alle services als een Elastic Compute Cloud Amazon Machine Images (EC2 AMI) door middel van een Animator (Netflix, 2013). Deze images worden dan gedeployd als een EC2-instance, waardoor ze gebruik kunnen maken van Amazons Auto Scaling Groups (Amazon Web Services, sd). Auto Scaling Groups verdeelt de werkdruk over de verschillende services en als het nodig is kan een extra instantie worden gedeployd.
Het nadeel van Service Instance per Virtual Machine is dat voor iedere service een nieuwe VM-image moet worden gebouwd. Dit gaat traag en kost veel tijd. Hierdoor zal ook het uitbrengen van een nieuwe versie traag zijn.
5.6.4. Service Instance per Container
Bij Services Instance per Container draait iedere service in een aparte container. Een container is een virtuele machine die draait op het OS-level (Wikimedia Foundation, Inc, 2020). Een voorbeeld van deze technologie is Docker of Solaris.
De voor- en nadelen van een Service Instance per Container zijn vergelijkbaar met de voor- en nadelen van een Service Instance per Virtual Machine. Bij een container is de service ook geïsoleerd, goed schaalbaar en is het mogelijk om de services goed te monitoren. Daarnaast maken de containers gebruik van de lightweight-technologie (Docker Inc, sd). Een ander voordeel van containers is dat ze snel builden in
vergelijking met een VM.
Er zijn ook een aantal nadelen aan containers. Een container is minder goed beveiligd dan een VM. Dit komt doordat gebruikgemaakt wordt van hetzelfde OS. Daarnaast is het landschap van de containers nog niet zo groot als die van VM’s. Er zijn wel een aantal grote spelers voor het hosten van containers, zoals Amazon Elastic Container Service (Amazon Web Services, Inc, sd) en Google.
5.6.5. Conclusie
Voor het prototype wordt gebruikgemaakt van Service Instance per Container. Het prototype moet individueel kunnen werken en Containers zijn sneller en lichter dan VM’s. Bij Verzuimsignaal wordt gewerkt met Docker, waardoor Service Instance per Container de voorkeur heeft. Voor het deployen naar de cloud heeft Google een uitgebreide tutorial (Google, 2020).
5.7. Wat zijn de voor- en nadelen voor
Verzuimsignaal om over te stappen naar een
microservice-architectuur?
In paragraaf 5.2. is besproken wat de voor- en nadelen zijn van een
microservice-architectuur. Aan de hand hiervan kunnen de voor- en nadelen voor Verzuimsignaal worden benoemd wanneer het bedrijf overstapt naar een
microservice-architectuur. Om deze voor- en nadelen te onderzoeken, is een gesprek gevoerd met een van de developers van Verzuimsignaal, René.
In het overleg met René is benoemd dat het gebruik van microservices complex is. Het gaat hier niet om de complexiteit van een microservice, maar om de verbindingen tussen de verschillende microservices die het complex maken. René heeft verteld dat in de huidige situatie alles al met elkaar verbonden is en dat dit heel complex is.
Voordelen:
● Een microservice is sneller te begrijpen dan een monoliet.
● Doordat de microservices individueel werken, zijn bugs sneller te traceren in een microservice [P1].
● Omdat een microservice individueel functioneert, kan één service draaien op een geheel andere taal dan de rest van de microservices.
● Wanneer één service defect is, heeft dit weinig tot geen impact op de rest van de services [P2].
● Teams binnen de organisatie kunnen worden verdeeld in kleinere teams en ieder team kan een microservice onder zijn beheer nemen.
● Door de performance van de microservice te meten, kan worden geanalyseerd welke microservices veel of weinig worden gebruikt. Op basis hiervan kan een gebruiker de microservice upscalen of downscalen [P5].
● Momenteel wordt de database belast door het uitvoeren van zware queries. Door gebruik te maken van event-sourcing en CQRS kan de nodige data worden geprojecteerd en hoeven er geen zware queries te worden uitgevoerd om de data te genereren. Hierdoor kunnen de nodige views worden gemaakt om de data te scheiden [P3].
● Door gebruik te maken van Domain events, event-sourcing en views kunnen fundamentele aanpassingen makkelijker worden doorgevoerd [P4].
Nadelen:
● Het kost tijd om de applicatie om te zetten naar een microservice-architectuur.
● Het concept en hoe microservices werken moet nog geïntroduceerd worden binnen in de organisatie.
● Er komt een aantal nieuwe technologieën het bedrijf binnen. Bij Verzuimsignaal is er nog weinig kennis over de manier waarop deze technologieën werken of hoe ze gebruikt kunnen worden.
5.8. Hoe zou een microservice-architectuur eruitzien
in de huidige omgeving van Verzuimsignaal?
Om een beter beeld te krijgen hoe de architectuur van Verzuimsignaal er uit kan komen te zien, is onderzoek gedaan naar welke patterns gebruikt kunnen worden en welke problemen ze oplossen (zie hoofdstuk: 5.3, 5.4, 5.6 (Richardson, sd)). Van al deze verschillende patterns is een lijst opgesteld voor de mogelijke architectuur. In deze lijst staat welke pattern gebruikt wordt voor het ontwerp, waarom deze gebruikt wordt en welke pattern gebruikt gaat worden voor het prototype.
Nr. Pattern Waarom? Prototype
1.
Microservice-architecture Door gebruik te maken van microservice is de applicatie op te delen in kleinere services, die beter onderhouden kunnen worden [P1]. Daarnaast hebben de services weinig impact, waardoor de applicatie niet stil komt te liggen wanneer een service uitvalt [P2].
✔
2. Decompose
by subdomain Bij decompose by subdomain wordt de monolite opgedeeld in kleinere services. Dit is nodig om te bepalen welke onderdelen iedere service gaat beheren.
✔
3. Database per
Service Hierbij heeft iedere service een eigen database. Hierdoor wordt de data per service gescheiden en beheerd [P3].
✔
4. CQRS CQRS wordt gebruikt om het lezen en het schrijven van de data gescheiden te houden. Hierdoor kan de database geoptimaliseerd worden voor lezen en schrijven. Daarnaast kan de
performance van de database beter worden
gewaarborgd, omdat het schrijven en het lezen van elkaar gescheiden is en kan worden ingezien [P5].
✔
5. Aggregate Het aggregate-pattern wordt gebruikt om
businesslogica te verwerken in de microservice. Hierbij wordt vooraf bepaald wanneer een domainevent wordt gepubliceerd.
✔
6. Domain
events Domain events wordt gebruikt om de businesslogica van de service aan te houden. Hierbij wordt een event gepost wanneer de data wijzigt binnen de services. Hierdoor blijft de data in de service constant.
✔
7. Event-sourcin g
Event-sourcing wordt gebruikt om de data tussen de verschillende services synchroon te houden.
Hierbij wordt gebruikgemaakt van eventlogs in plaats van de huidige status. Deze keuze is
gemaakt omdat de kern van Verzuimsignaal ligt bij protocollen en het uitvoeren van taken die
hieronder vallen. Al deze taken moeten uitgevoerd worden binnen een bepaalde tijdsperiode. Dit wordt aan de gebruiker getoond als een tijdlijn. Dit is efficiënter wanneer de data al is opgeslagen in een log.
8. Messaging Messaging wordt gebruikt voor de communicatie tussen de verschillende services. Hierbij wordt gebruikgemaakt van een pub/sub-systeem.
✔
9. Self-registrati
on Er wordt gebruikgemaakt van self-registration. Hierbij zal een service zichzelf gaan registeren bij het de pub/sub-systeem.
✔
10 API-gateway Via de API-gateway is iedere service in de microservice-architectuur te benaderen.
✔
11. Access Token Door middel van Access Tokens wordt de
autorisatie van een gebruiker geregeld. Dit wordt bij de API-gateway afgehandeld.
✔
12. Service component test
De Service component test wordt gebruikt om de
service in isolatie te testen. ✔
13. Service-per-c
ontainer Er is voor Service-per-container gekozen omdat deze snel te bouwen en te deployen zijn. ✔ 14. Single service
per host Er is voor single service per host gekozen omdat het hierdoor mogelijk is meerdere van dezelfde services te hosten. Daarnaast is de performance van iedere service meetbaar (P5).
✔
15. Service deployment platform
Een voorbeeld van een service deployment platform is een Kubernetes. Hierbij zijn er mogelijkheden om de services automatisch schaalbaar te maken. Daarnaast is er een
dashboard dat de huidige status van de services bij kan houden.
✔
Tabel 2: De gekozen patterns voor het ontwerp en het prototype.
5.8.1. Microservice-architectuurplaat
De architectuur in Figuur 5 is gebouwd met de patterns die zijn toegelicht in
paragraaf 5.8. Hierbij is in acht genomen dat de huidige monolithische applicatie niet in één keer overgezet kan worden. Dit kan het beste in delen gedaan worden. Bij het ontwerpen van deze architectuur is gebruikgemaakt van (Bologna, 2018).
Figuur 5: Microservice-architectuur Verzuimsignaal.
In de toekomstige architectuur van Verzuimsignaal is de huidige applicatie opgedeeld in twee delen: de monoliet en de microservices. Dit is gedaan om de transactie van een monolithische architectuur naar een microservice-architectuur weer te geven. De user kan in dit geval gebruikmaken van de API-gateway en van de monoliet.
Wanneer de user gebruik wil maken van de microservices, moet hij een request sturen naar API-gateway. Hierbij wordt de autorisatie uitgevoerd door middel van een accestoken. De API-gateway stuurt het request door naar het REST API-point van de service. De request wordt binnen de service verwerkt. Wanneer de request een update, delete of een post is, wordt de Aggregate Root (business logica) van de service benaderd. Hierna wordt een domain-event afgevuurd om de mutatie door te zetten. Dit event komt terecht bij de pub/sub-services. Hier wordt het event
doorgestuurd naar de eventstore en wordt het in de eventstream gezet. De eventstore slaat alle events op en wordt gezien als de absolute waarheid. De eventstore kan later gebruikt worden voor een playback. Hierbij worden alle events die in de eventstore staan weer afgespeeld via de eventstream. De services kunnen deze events ontvangen door te subscriben op de verschillende channels. Bij het ontvangen van een event wordt binnen de service gekeken naar welke views geüpdatet moeten worden.
Wanneer de user de monolite gebruikt en er een mutatie van data is, moeten deze data worden gesynchroniseerd met de microservice. Dit wordt gedaan door de eventemitter in de monolite. Hierbij wordt een event gemaakt en doorgestuurd naar de pub/sub-services. Hierdoor worden de data geüpdatet in de eventstore en in de microservices. De data kunnen op twee manieren in de monolite geüpdatet worden. Het is mogelijk om de monolite te subscriben op alle events en hierdoor alle data updaten. De andere manier is om de data niet te updaten, maar gebruik te maken van de data in de microservices. Op deze manier wordt de monoliet langzaam afgebouwd en wordt meer gericht op de microservices.
Deployment platform
Iedere service in de microservice-architectuur wordt gebouwd in zijn eigen Docker-container. Dit heeft als voordeel dat het kan worden gedeployd door een deployment platform zoals Kubernetes. Kubernetes kan iedere container deployen in zijn eigen pod. Wanneer de load voor een service hoog wordt, zorgt Kubernetes ervoor dat er een pod bij wordt gezet. Hierdoor wordt auto-scalen mogelijk gemaakt in de microservice-architectuur (kubernetes, 2020). Daarnaast heeft Kubernetes monitoring zoals het Dashboard UI, waarbij de status van iedere pod wordt weergegeven.
5.9. Proof of concept
Tijdens het onderzoek is begonnen aan het ontwikkelen van een PoC. Hiermee wordt duidelijk hoe Kafka in de praktijk werkt zie hoofdstuk 5.5.5.. Het ontwikkelen van het PoC verliep in het begin stroef, omdat de onderzoeker nog weinig kennis had van Docker en van de mogelijkheden om met Docker de Kafka-omgeving te benaderen. Nadat enige tijd aan het prototype was gewerkt, had de omgeving een aantal brokers met een aantal verschillende topics. Berichten konden worden verstuurd naar de topics door middel van producers. Deze berichten werden ontvangen door
consumers. Daarnaast was het mogelijk om woorden te tellen door gebruik te maken van streaming.
Het struikelpunt was dat Verzuimsignaal PHP gebruikt als primaire programmeertaal. Het was dus ook aangeraden om dit als taal te gebruiken in het prototype. Dit was toen nog geen probleem, aangezien er een PHP-extension (php-rdkafka, 2020) is om te kunnen communiceren met de Kafka-server. Het installeren van deze extension duurde lang. Dit kwam doordat er problemen waren met de versies van verschillende libraries die moesten worden geïnstalleerd. Nadat de extensions geïnstalleerd waren, was het mogelijk een bericht te sturen via een producer die geschreven was in PHP. De Kafka-server ontving het bericht en door middel van de optie
auto.create.topics.enable, maakte hij een nieuw topic aan. Echter, wanneer die topic werd geopend via de PHP-client, kwam er een time-out met de melding dat de broker niet gevonden kon worden. Wanneer deze topic werd geopend met Kafka-cliënt, was het niet mogelijk om de topic te openen. Er waren twee mogelijke punten waar de fout kon zitten. De eerste mogelijkheid was dat er een probleem in het netwerk was. Hiervoor is in Docker een netwerk opgezet waarmee Kafka en de PHP-client in
hetzelfde netwerk zitten. Daarnaast is Kafka zo ingesteld dat het een een aparte poort heeft voor het communiceren met applicaties binnen hetzelfde
Docker-netwerk, hetzelfde lokale en externe netwerk. Dit had helaas geen effect op het probleem. De andere mogelijke oplossing was het gebruiken van meerdere brokers voor een topic. Beide oplossingen hadden geen effect. De onderzoeker had zijn technische begeleider gevraagd om mee te denken, maar hij kwam er ook niet uit. Na twee weken zoeken naar een oplossing, en de verschillende github repositories getest te hebben, was er steeds meer tijdnood. Hierdoor is in overleg met de
technische begeleider Gerwin besloten om een andere weg in te slaan en gebruik te maken van Redis. Dit is gedaan om een aantal redenen. Eén van deze redenen is dat in Redis al een PHP-framework is ingebouwd, zoals Laravel (laravel, sd). Hierbij wordt Redis gebruikt als database, maar het is ook mogelijk om ervoor te kiezen om de pub/sub-functionaliteiten te gebruiken. Hierbij is een klein demo-project (Spatie, sd) gevonden dat een voorbeeld weergeeft van event-sourcing. Dit project is open-source en wordt als basis gebruikt om de rest van de functionaliteiten toe te voegen. Een andere reden is tijd. Bij het opzetten van de Kafka-omgeving is veel tijd verstreken en door gebruik te maken van het Laravel-event-sourcing project kon deze tijd worden ingehaald.
5.10. Conclusie onderzoek
In dit onderzoek is een antwoord gezocht op de hoofdvraag: Hoe kunnen wij onze monolithische architectuur omzetten naar (micro)services? Om deze vraag te kunnen beantwoorden, is de hoofdvraag opgedeeld in een aantal deelvragen.
Gekeken is naar de hoofdreden van Verzuimsignaal om over te stappen naar een microservice-architectuur. Om dit te bepalen, is een aantal interviews afgenomen. Hieruit bleek dat de applicatie te groot en complex is geworden om nog snel en effectief te kunnen werken.
Daarnaast is duidelijk geworden dat een microservice-architectuur uit vele
verschillende componenten en patterns bestaat. Om die reden moet eerst worden onderzocht welke pattern het best bij het betreffende systeem past. Iedere pattern heeft zijn voor- en nadelen.
Na het onderzoek naar de microservice-architectuur is onderzocht hoe een
microservice-architectuur het beste kan worden uitgerold in een cloud-omgeving. Hierbij is gekeken naar de verschillende patterns die voor deployment worden gebruikt en is gekozen voor single service per host. Hierdoor is het gemakkelijk om één service op te bouwen in een container en van deze container kunnen meerdere instanties gedeployd worden (horizontaal schaalbaar). Ook worden de volgende
Met deze informatie over microservices is een gesprek gevoerd met René. Hierbij zijn alle voor- en nadelen van het overstappen naar een microservice-architectuur
besproken. Hieruit bleek dat het grote nadeel van overstappen is dat het veel tijd kost. Het kost veel tijd om de huidige applicatie om te zetten naar een microservice. Het grootste voordeel is dat de services individueel van elkaar kunnen werken.
Hierdoor is het mogelijk om één service te ontwerpen en op te schalen, zonder dat de andere services hier last van hebben.
De laatste deelvraag gaat over hoe een microservice-architectuur eruit zou zien in de huidige omgeving van Verzuimsignaal. Om deze vraag te beantwoorden, is eerst een lijst opgesteld met alle patterns die interessant zijn om te gebruiken. Met deze lijst in gedachten is een architectuurplaat opgesteld voor de toekomstige situatie. In dit ontwerp zijn de monoliet en de microservices getekend. Hierbij stuurt de monoliet events door naar de pub/sub-service om de data te synchroniseren, maar de service zal de data van de monoliet niet updaten. Hierdoor kunnen stukken van de monoliet vervangen worden door requests naar de microservices. Op deze manier wordt de monoliet steeds kleiner en de microservice-architectuur steeds groter.
Met behulp van deze informatie is een gesprek gevoerd met Gerwin, de technisch begeleider. Hiervoor is een lijst opgesteld met de system-requirements en de user-requirements voor het prototype. Het is niet realistisch om de gehele
microservice-architectuur te bouwen voor Verzuimsignaal. Er is voor gekozen om één microservice uit te werken, namelijk het registreren van verzuim.
NR. System-requirements Prio
S.01 De microservice werkt zelfstandig en mag niet afhankelijk zijn
van de huidige applicatie van verzuim. must
S.02 De microservice maakt gebruik van Event sourcing pattern met
Redis als ondersteunende technologie. must
S.03 De microservice maakt gebruikt van CQRS pattern. should S.04 De microservice is te benaderen via de huidige applicatie. should S.05 De microservice wordt opgezet in een Docker-omgeving zodat
het Service Instance per Container pattern kan worden toegepast.
must
Tabel 3: System requirements.
NR. User requirements Prio
U.01 De gebruiker kan zich registreren. could
U.02 De gebruiker kan inloggen op de applicatie. Could
U.03 De gebruiker kan uitloggen. could
U.04 De gebruiker kan zich autoriseren door middel van een API-key.
could
U.05 De gebruiker kan een werknemer toevoegen. must U.06 De gebruiker kan een werknemer verwijderen. must U.07 De gebruiker kan een werknemer ziekmelden. must U.08 De gebruiker kan een werknemer gedeeltelijk hersteld melden. must U.09 De gebruiker kan een werknemer volledig hersteld melden. must U.10 De gebruiker kan een overzicht ophalen van alle werknemers. must U.11 De gebruiker kan een overzicht ophalen van alle
verzuimperiode van een werknemer. must
U.12 De gebruiker kan een overzicht ophalen van alle verzuim
U.13 De gebruiker kan een overzicht ophalen van alle zieke
werknemers. must
U.14 De applicatie houdt rekening met een samengestelde verzuimmelding. must Tabel 4: User-requirements.