Architectuur - seizoen 1

Wie is de Mol Online seizoen 1 werd volledig gehost op een Synology DS216+. Op die Synology NAS draait Linux, met daar bovenop een specifiek Synology besturingssysteem genaamd DSM. Binnen DSM draaide een webserver (Apache HTTP Server met PHP) en een MariaDB database. De gehele omgeving was geïmplementeerd in PHP, met een beetje jQuery. Het applicatielandschap was daarmee zeer eenvoudig; frontend requests kwam binnen op de webserver en vanuit daar werden waar nodig SQL queries gedaan op de Maria database.

Alhoewel dit in de basis prima werkte, was het voor het spel echt noodzakelijk om tweeweg communicatie mogelijk te maken. Een manier waarop de 'server' zelf ook actief berichten kan sturen naar de client, of deze zelfs kan besturen. Websockets is daar bijvoorbeeld een mogelijkheid voor, maar dat was in de technology stack van seizoen 1 nog niet beschikbaar. Op sommige plaatsen werd er noodgedwongen een 'Ajax ping' gedaan naar de server iedere seconde, puur om te checken of er "nieuwe berichten" waren.

Daarnaast is PHP niet mijn expertise. Beroepsmatig gebruik ik voor bijna alles Java, en is het dus voor mij persoonlijk een veel efficiëntere keus om Java te gebruiken. Daarnaast is Java een professionelere taal dan PHP, alhoewel PHP goeroes dat natuurlijk ontkennen. Omdat het aan de praat krijgen van Websockets in PHP in mijn specifieke setup redelijk onmogelijk leek, leek een rewrite van het server-side deel naar Java een voor de hand liggende keuze voor seizoen 2.

Architectuur - seizoen 2

En dus moesten er een aantal drastische wijzigingen doorgevoerd worden. De belangrijkste wijziging was de splitsing in een frontend applicatie en een backend applicatie. De frontend bleef PHP, server-side werd Java. Om zo dicht mogelijk te blijven bij mijn eigen expertise koos ik daarbij voor een OSGi Java applicatie op een Apache Karaf runtime, met JPA als persistence laag om met de Maria database te communiceren. Het toevoegen van Websockets was vervolgens een peuleschil. Deze splitsing gaf ook de nodige hoofdpijn, omdat de client nu cross-site Ajax requests moest uitvoeren. De PHP webserver draait op wieisdemolonline.nl, de Java server op api.wieisdemolonline.nl. Wel geeft dit een mooie scheiding tussen frontend en backend waarbij de backend Java server dus geheel headless opereert.

Apache Karaf draaide in eerste instantie als Docker image binnen Docker, omdat dat binnen DSM nu eenmaal handig in het gebruik is. De combinatie van Docker en de Ajax preflight requests die nodig zijn vanwege de cross-site Ajax requests bleken echter een nachtmerrie. Op de 10 requests kreeg 1 er een 502 Bad Gateway foutmelding. En dat is een beetje jammer, omdat daardoor bijvoorbeeld voorwerpen in het spel niet gepakt konden worden of zomaar verdwenen. Uiteindelijk bleek Docker daarbij de oorzaak van het probleem te zijn. Docker moest zelf de requests vanaf de Proxy server weer doorsturen naar de embedded Karaf server, maar dat ging af en toe fout. Na Googelen op dit specifieke probleem was het duidelijk dat ik lang niet de enige was die hier tegen aan liep. En dus besloot ik afscheid te nemen van Docker en Apache Karaf dan maar gewoon direct vanaf de Linux shell te draaien.

Ondertussen waren er ook performance issue met het afhandelen van de Ajax requests. Ook dit bleek deels aan Docker te liggen, of eigenlijk vooral aan de hoeveelheid geheugen die de NAS nodig had. De NAS was maar uitgerust met 2 GB intern geheugen, wat gewoon weg te weinig was om alles fatsoenlijk op te draaien. Officieel was 2 GB de max, maar met wat googelen waren al snel howto's gevonden voor een upgrade naar 8 GB. De NAS werd uitgerust met 8 GB, en het performance probleem was daarmee opgelost.

Vanuit Karaf gebruik ik JPA om met de Maria database te communiceren. Een extra proxy server (NGINX) was nodig om het verkeer naar api.wieisdemolonline.nl door te loodsen naar Karaf. Dat verkeer kan vanaf de client komen, maar ook vanuit de PHP frontend die zelf ook nog requests doet. Het architectuurplaatje ziet er uiteindelijk zo uit: