Een kijkje onder de motorkap



Vanwege de populariteit en veelvuldig gebruik van opensource software kan GEZINSMAN.NL in korte tijd een betrouwbare web applicatie opzetten naar de wensen van de klant. Hierbij wordt gebruik gemaakt van korte development cycli, zodat de klant en eindgebruiker direct het resultaat zien en zodoende tijdig kunnen bijsturen.

Een complexe multi-user, multi-device applicatie als GEZINSMAN.NL bestaat uit verschillende lagen. Dit kan als een ijsberg als volgt worden geillustreerd:



  1. Het topje van de ijsberg is de userinterface. Dit is alles wat de gebruiker ziet en draait in een Chrome browser, op de hardware van de eindgebruiker (PC, tablet of mobiel). Met behulp van moderne webtechnieken (PWA, service workers) wordt via de browser de eindgebruiker een look en feel aangeboden van een applicatie.
  2. De data op de server kan via een rest api worden opgehaald. Hiervoor zijn meerdere servers beschikbaar in een schaalbare architectuur, waarover de client connecties worden verdeeld. Bij toenemende connecties zullen meerdere servers worden geactiveerd om de load te verdelen.
  3. De data op de server wordt bewaard in een cluster van databases, die in een redundante master/slaves configuratie is opgezet. In deze configuratie wordt de database gerepliceerd op meerdere servers. Dit verhoogt de betrouwbaarheid en onderhoudbaarheid van het systeem aanzienlijk.


Een greep uit onze tools en technieken

  • Openstreetmap
  • Popper-JS
  • Hammer-JS
  • Full Calendar
  • Linux servers
  • Cloud deployment
  • SSL/HTTPS


GEZINSMAN.NL garandeert een hoge systeembetrouwbaarheid en gebruikersgemak dankzij

  • clustering van redundante databases
  • distributie van functionaliteiten door gebruik van microservices en javascript engines
  • client-side loadbalancing
  • progressive web apps.


Clustering

Een cluster van data servers staat garant voor een snelle, betrouwbare en schaalbare data interface. Dit cluster is voorzien van een lokaal netwerk, waarmee de databases onderling worden gesynchroniseerd.

Een Web hosting provider voorziet in een domein en hosts de statische datafiles.




Deze opzet maakt een systeem upgrade en database upgrade mogelijk met zero downtime.

In onderstaande schema is dit geillustreerd in 7 stappen.



  1. Initiele toestand, waar gm02 repliceert van master gm01
  2. gm02 is uitgeschakeld, alle R/W connecties zijn omgeleid naar gm01
  3. gm02 is ge-update naar het nieuwe datamodel dm02
  4. data van gm02 wordt hersteld door de data van dm01 te kopieren naar dm02
  5. gm02 is ingeschakeld, gm01 is uitgeschakeld en alle connecties zijn omgeleid naar master gm02
  6. gm01 is ge-update naar het nieuwe datamodel dm02 en ingeschakeld als replicerende slaaf
  7. Tenslotte worden alle connecties hersteld. Nu zijn de rollen echter omgedraaid: gm01 repliceert nu van master gm02!


Volledig gedistribueerd

Het systeem is volledig gedistribueerd, waarbij gebruik wordt gemaakt van Java microservices en Javascript engines. We kunnen de gezinsman.nl infrastructuur als volgt grafisch weergeven:

Ons front-end systeem draait lokaal in een webbrowser op uw laptop, tablet of smartphone en bestaat uit meerdere controllers en services, waarvan de restservice de belangrijktste is. Deze verzorgt de encrypte communicatie met de back-end. De front-end zorgt, met behulp van de controllers, voor de interaktie met de gebruiker.

Ons back-end systeem draait in de cloud en bestaat uit meerdere microservices, bijvoorbeeld de gezinsman en budgetcoach. Elke microservice is verantwoordelijk voor een bepaalde afgebakende functionaliteit van het systeem.



In dit overzicht van het systeem bestaat elke microservice uit een cluster van servers. Deze servers zijn in master/slave configuratie of ook wel active/passive configuratie. Het systeem kan meerdere slaves (of passive) servers hebben. Elke client heeft zowel een write- als read connectie. De write connectie is altijd naar de master server. De read connectie kan elke server in de connectie zijn. Welke deze is moet door het systeem zelf online worden bepaald aan de hand van CPU- en netwerkload metingen.

Doordat het systeem gedistribueerd is in plaats van monoliet is het ondermeer schaalbaar, fout tolerant en redundant. Ook biedt een gedistribueerd systeem betere mogelijkheden om de system load te verdelen.


Inversion of Control

Bij Inversion of Control (IoC) wordt het zogenaamde "Don't call us, we call you." principe toegepast. Een process laat een referentie naar een functie achter bij een ander process met daarbij de boodschap dat als er bijvoorbeeld iets verandert om dan een functie van hem aan te roepen. Het voordeel is dus voor het process dat deze dus niet periodiek moet pollen naar data. IoC wordt ook wel publish/subscribe genoemd. Het publish/subscribe mechanisme wordt door de microservices gebruikt om onderling data uit te wisselen. Het gaat met name om de user en session tabellen, die in de gezinsman microservice worden bijgehouden, maar die ook nodig zijn in de budgetcoach microservice.



In bovenstaande voorbeeld zien we het publish/subscribe mechanisme afgebeeld. Het begint bij een proces in de budgetcoach die zich abonneert op tabellen van de gezinsman database. In deze subscribe data zit een endpoint URL, waar de gezinsman zijn data kan posten. Zodra een create, update of delete (CRUD) aktie plaastvindt op de geabonneerde tabellen van gezinsman, dan zal deze de gewijzigde data publiceren naar de meegestuurde endpoint URL.



Schaalbaar

Elke microservice bestaat uit een aantal servers, die in master/slave configuratie draaien. De microservice heeft als doel om één of een beperkt aantal funkties uit te voeren. Bijvoorbeeld de gezinsman microservice voert de taken administratie, ruilmoeder, kalender en geotracker uit. De budgetcoach microservice voert de taken boodschappenlijst, eetclub en budgetcoach uit. Het voordeel van een microservice is het opdelen van een groot systeem in kleinere behapbare delen. Hierbij heeft elk deel een eigen datamodel, die dus onafhankelijk kan worden bijgehouden. Door het opdelen van het systeem in microservices is het mogelijk om een groot en complex systeem overzichtelijk, schaalbaar en onderhoudbaar te maken. Zo heeft elke microservice een eigen software boom met een eigen onafhankelijke versie beheer.

Fout tolerant

Een gedistribueerd systeem heeft ook als voordeel, dat deze functioneel blijft in het geval er systeemfouten optreden. Mocht om één of andere reden een microservice falen, dan is slechts een deel van het systeem onbereikbaar. Een groot gedeelte zal nog blijven functioneren (degraded functionality). In een monoliet systeem zal een enkele fout hoogstwaarschijnlijk tot totale system failure leiden.

Redundant

Een ander voordeel is dat elke microservice op een andere manier en andere plaats gedeployed kan zijn. Ze hoeven niet in dezelfde server of zelfs datacenter te zijn. De ene microservice kan in een datacenter in Rotterdam draaien op een virtuele server en de tweede in Gouda op dedicated hardware bij wijze van spreken.



Client-side loadbalancing

Bij traditionele loadbalancers bepaalt een centrale orgaan aan de server-side welke fysieke server gebruikt moet worden door een client. Dit is te vergelijken met systemen die bij veel overheidsgebouwen worden gebruikt zoals een stadhuis. Je komt binnen, trekt een nummer uit een machine en neemt plaats in de wachtkamer. Het systeem kijkt dan welke loketten beschikbaar zijn en bepaalt welk loket je moet nemen. De achilleshiel in dit systeem is natuurlijk het central orgaan. Als deze uitvalt en niet vervangen wordt zal er chaos ontstaan.

GEZINSMAN.NL maakt gebruik van client-side loadbalancing. Hierbij bepaalt een client sessie zelf welke servers hij zal gebruiken. Hierbij maakt hij gebruik van een algoritme, die meerdere meetgegevens van de server in acht neemt om dit te bepalen. Dit is in feite te vergelijken met een supermarkt, waarbij meerdere kassa's zijn geopend. Klanten kiezen dan op basis van eigen observaties (lengte rij, belading winkelwagens in de rij, snelheid kassa dame, etc.) of er van rij wordt gewisseld. Ook als een nieuwe kassa wordt geopened zullen een aantal klanten die vooral aan het einde van de rijen staan wisselen naar deze nieuwe kassa. Het voordeel is dus dat de intelligentie van loadbalancing is gedistribueerd over de clients en dat het systeem hiermee meer fout tolerant is dan de traditionele wijze.



Progressive Web App

De progressive web app heeft het voordeel van een website, maar met de look en feel van een native android of IOS app. Deze kan dan ook apart worden geinstalleerd vanuit de browser en heeft (beperkte) offline functionaliteit. Bij een goede PWA zal de gebruiker het gevoel krijgen, dat hij met een native app werkt.

Er zijn tal van voordelen te bedenken voor een web app ten opzichte van een native app. Hier zijn de belangrijkste op een rij:

  • Ten eerste natuurlijk de ontwikkeltijd en kosten. Deze zijn voor de front-end aanzienlijk minder, aangezien we hier slechts met standaard webbrowser technieken te maken hebben als html, javascript en css.
  • Daarnaast zijn updates veel vaker en aanzienlijk éénvoudiger te realiseren. Voor cosmetische updates is slechts een update van css of html files op de webserver voldoende. Vaak wordt dit echter gecombineerd met een update van de back-end, wat door onze microservice en master/slave architectuur mogelijk is met zero downtime.
  • De PWA is responsive. Met javascript libraries als angularjs, hammerjs, bootstrap, jquery, popperjs en openlayers is het mogelijk om een native look en feel te realiseren. Daarnaast heb je als voordeel dat de app device onafhankelijk is! Deze draait net zo gemakkelijk op een android phone/tablet als op een IOS iphone/ipad in portrait of landscape mode.
  • De PWA bewaart een deel van de data die ontvangen is van de server in een tijdelijke lokale opslag (cache). Dit maakt het mogelijk om de app in beperkte modus offline te laten functioneren.
  • In tegenstelling tot een native app, wordt voor de communicatie met een PWA alleen dataverkeer over SSL toegestaan. Dit houdt in dat het onmogelijk is voor buitenstaanders om mee te luisteren met het verkeer tussen de gebruiker en de server.
  • De PWA is vanuit de webbrowser éénvoudig te installeren met één druk op de knop. Wanneer een gebruiker de website bezoekt zal deze een pop-up tonen, waarin gevraagd wordt om de PWA te installeren. Je krijgt dan net als bij een native app een icoontje op het apparaat, die de PWA in een webbrowser opstart. Dit geeft de gebruiker de indruk dat een native applicatie wordt opgestart.
  • Als laatste voordeel, die genoemd moet worden, van de PWA boven een native app is de vindbaarheid. De app zal net als gewone websites door zoekmachines worden geindexeerd. En bij het slim opzetten van bepaalde keywords, kan je ervoor zorgen dat je app snel gevonden wordt door de gebruikers voor wie de PWA gemaakt is.