De "Reactive" hype

Posted on: 11/03/2020 by: Koen Vanderkimpen

U heeft het buzzword "Reactive" misschien al gehoord. Deze nieuwe architecturale principes om software mee te bouwen zouden heel wat van de "problemen" oplossen waar huidige software mee kampt. De Reactive Revolution zou systemen robuuster, resiliënter en flexibeler maken; klaar om toekomstige requirements sneller op te vangen. Maar wat is hier nu eigenlijk van op aan?

Een Beetje Geschiedenis

Het "Reactive" Manifest

De huidige hype rond Reactive Systems is ontstaan in de nasleep van het publiceren van het 'Reactive Manifesto'. Een manifest is een openbare verklaring die een aantal principes uiteenzet volgens een nadrukkelijke mening en vaak ook mensen uitnodigt deze te onderschrijven. Het reactive manifest werd een eerste keer gepubliceerd door iemand van de firma 'Lightbend', makers van een cloud platform dat volgens deze principes werkt. De tweede en huidige versie van dit manifest dateert van 16 september 2014. Het werd reeds door duizenden mensen onderschreven.

Wat zegt dit manifesto? Een systeem moet responsief, resiliënt, elastisch en message-driven zijn. In de eerste versie was dit nog interactief, resiliënt, schaalbaar en event-gedreven, maar men wou dit algemener gaan verwoorden. Er wordt in het manifest uiteraard iets dieper ingegaan op elk van deze aspecten, maar niet diep genoeg om nu precies te weten hoe je volgens deze principes software kan bouwen, en waar de naam "reactive" nu eigenlijk vandaan komt. Wat dit laatste betreft vinden we meer uitleg in een blogpost van de oorspronkelijke auteur, en in de eerdere versies van het manifest: het gaat om een aantal verschillende principes, die allemaal tot gevolg hebben dat het systeem beter en sneller zal reageren op allerlei zaken:

  • react to events: the event-driven nature enables the following qualities:
  • react to load: focus on scalability rather than single-user performance
  • react to failure: build resilient systems with the ability to recover at all levels
  • react to users: combine the above traits for an interactive user experience

Functional Reactive Programming

Het woord "reactive" zien we in de IT-geschiedenis echter nog veel eerder opduiken: het gaat dan om Reactive Programming. Dit is een manier om te programmeren die zich toespitst op het omgaan, op een declaratieve manier, met stromen van data en het propageren van veranderingen in die data (en ook met steeds binnenkomende nieuwe data). Ze is sterk verwant aan "Dataflow Programming".

Om het iets concreter te maken, kan men dit vergelijken met spreadsheets, zoals gekend van b.v. Excel. Wanneer men in een werkblad een gegeven in een cel verandert, veranderen onmiddellijk alle cellen die van dit gegeven zijn afgeleid, a.h.w. zonder dat er eerst nog expliciete berekeningen voor moesten worden verricht. Uiteraard gebeuren deze berekeningen wel op de achtergrond: Excel maakt dit transparant, net zoals reactieve programmeertalen dit doen voor hun datastromen: verandert er iets in de bron-stroom, dan volgt ook onmiddellijk de uitgangsstroom.

Aan het bovenstaande principe wordt dan nog Functioneel Programmeren toegevoegd. Dit is een manier van programmeren die zich focust op het vrijwaren van de eigenschappen van pure functies: functies die enkel rekening houden met hun argumenten (niet met toestand elders in het programma) en ook alleen maar een resultaat teruggeven (en dus ook niets veranderen aan de toestand van het programma). Functioneel programmeren maakt het veel gemakkelijker om over code te redeneren. Wanneer met dit doortrekt in een architectuur, bekomt men componenten die men gemakkelijker elastisch kan schalen, die men makkelijker redundant kan uitrollen tegen falen, etc.

Functioneel Reactief Programmeren is momenteel populair en wordt mogelijk gemaakt door een aantal frameworks die goed zijn in te bedden in bestaande platformen. Onder de noemer ReactiveX vinden we bijvoorbeeld ondersteuning voor dit paradigma voor een heel aantal populaire talen, vertaald in specifieke libraries per taal (o.a. voor Kotlin, Java, .Net, Scala, Python, C++, en Javascript). ReactiveX heeft behoorlijk wat invloed gehad op programmeren en krijgt nog steeds de nodige aandacht op conferenties. Het is goed om deze manier van programmeren als software ontwikkelaar in de toolbox te hebben.

Reactive voor Reactive

Software Ontwikkelaars die volgens de Reactive Principes werken, kunnen dit op hun website aangeven d.m.v. de volgende banner.

En wat heeft "Reactive Programming" nu uiteindelijk te maken met de eerder genoemde Reactive Systems? In principe kan je reactieve systemen implementeren zonder dit paradigma, maar het gebruik ervan maakt het bouwen van de systemen echter wel een stuk makkelijker. De middelen die worden voorzien door de reactieve programmeerframeworks maken het namelijk een stuk eenvoudiger om "reactief te zijn" wanneer men zo'n systeem bouwt. De meeste zaken die zo'n systeem in en uitgaan zijn immers te behandelen als datastromen waar men op moet reageren, met als meest typische voorbeeld de stroom van binnenkomende berichten/events.

Hoe is dit nu Beter?

Reactieve systemen zijn Cloud-native, en focussen op 4 zaken: Responsiviteit, Resiliëntie, Elasticiteit, en asynchrone communicatie via berichten. Uiteraard zijn de eerste 3 van deze kenmerken al voordelen op zich, maar hoe worden deze nu effectief verwezenlijkt?

Het belangrijkste element in de architectuur van Reactieve systemen is de asynchrone communicatie via berichten, meestal onder de vorm van Events. Doordat Consumenten en Producenten van Events elkaar niet hoeven te kennen, bekomen we een grotere onafhankelijkheid van deze componenten ten opzichte van elkaar. Men zegt dan ook dat ze 'loosely coupled' zijn. Daarenboven zorgt de asynchrone communicatie voor een kleinere latentie en hogere doorvoer van de gegevensuitwisseling tussen de componenten, wat de performantie ten goede komt en zodat de systemen meer 'Responsive' zijn. De losse koppeling of onafhankelijkheid is iets wat we ook reeds bij microservices als thema zagen: zulke componenten worden makkelijker elastisch schaalbaar t.o.v. elkaar en kunnen ook afzonderlijk redundant worden gemaakt, waardoor ze resiliënter worden tegen falen. Indien het berichtenuitwisselingssysteem een tijdelijke uitval van één van de componenten kan opvangen (door berichten te bufferen b.v.), is ook het systeem als geheel resiliënter dan een systeem waarbij er synchrone comunicatie wordt gebruikt en elke component onmiddellijk antwoord verwacht van een andere.

Uiteraard moeten in het asynchrone geval de componenten die falen ook wel zo snel mogelijk terug online komen, zodat berichten (inkomende datastromen) zo snel mogelijk worden afgehandeld en er in het systeem als geheel geen te grote wachttijden ontstaan (wat ook een vorm van onbeschikbaarheid is).

Verschil met Event Driven Architecture?

De hier opgesomde voordelen lijken sterk op de voordelen van Event Driven Architecture (EDA), en reactive maakt ook gebruikt van Events. Waar zit dan precies het nieuwe?

De belangrijkste nieuwigheid zit hem in dit geval in de schaal en de benodigde performantie van deze systemen. Waar men in een traditioneel publish-subscribe model af en toe een berichtje kreeg, zit men nu met stromen van data die eigenlijk volcontinu de componenten binnen het systeem bombarderen. Het schaalbaar en elastisch, en ook simpelweg efficiënt maken van elke afzonderlijke component, was nog nooit zo belangrijk.

En dan nog kan het gebeuren dat één component niet meer kan volgen. Er is dan zogezegd een te grote druk (pressure) op de component. Om te vermijden dat deze bezwijkt, heeft men een mechanisme nodig om de rest van het systeem, en dan voornamelijk de bron van de te grote druk, te informeren. Als dit ervoor kan zorgen dat de druk minder wordt, dan kan de component blijven werken en dan is dit voor het systeem als geheel minder erg dan wanneer deze weg zou vallen.

Dit terugkoppelingssignaal noemen we het aangeven van back pressure (de back pressure zelf is het niet meer kunnen volgen; het niet aankunnen van de inkomende 'druk'). Het zorgt er dus voor dat het bronsysteem wat minder berichten naar de desbetreffende component zal sturen. Zoiets kan natuurlijk verder propageren doorheen het hele systeem; uiteindelijk kan dit zelfs bij de gebruiker geraken, die dan een mindere performantie merkt. Maar dit is uiteraard nog altijd beter dan een plots falen (graceful degradation). Andere componenten in het systeem kunnen hier op hun beurt ook op gaan reageren en meer middelen beginnen vrijmaken op de onderliggende infrastructuur, zodat men kan gaan schalen om de verhoogde druk beter aan te kunnen.

Het monitoren van falende componenten gaat bij Reactive systemen ook verder dan de traditionele monitoring die we zien vanuit de infrastructuur en op het niveau van het PaaS platform. Het is deels ingebouwd in de systemen zelf, zodat deze ook zelf de verantwoordelijkheid kunnen nemen. Men maakt hiervoor o.a. gebruik van het zogenaamde actor model en van supervision trees. In detail ingaan op deze zaken zou ons voor deze blog te ver leiden.

Kortom, een Event Driven Architecture vormt de basis waarop allerlei andere, verregaandere zaken mogelijk worden, om uiteindelijk te komen tot iets wat dan "Reactive" kan worden genoemd.

Besluit

Reactive systems zijn bedoeld om op grote schaal enorme hoeveelheden werk te verzetten, en dit met een sterke resiliëntie. Ze zijn specifiek ontworpen om optimaal in een Cloud te kunnen werken.

De truuk bestaat hem eruit de architectuur zodanig op te bouwen dat elke component op zich sterk staat, maar dat ook de communicatie tussen de componenten meehelpt om onverwachte zaken op te vangen. Het belangrijkste paradigma van Reactive is de asynchrone communicatie, meestal onder de vorm van Events. Daarnaast is het ook nuttig om bij de implementatie gebruik te maken van Functional Reactive Programming.

 

 

Interssante bronnen

https://4everinbeta.com/2015/01/15/is-reactive-programming-more-than-just-hype/

http://www.reactive-streams.org/

https://blog.redelastic.com/what-is-reactive-programming-bc9fa7f4a7fc

https://itnext.io/demystifying-functional-reactive-programming-67767dbe520b

https://www.scnsoft.com/blog/java-reactive-programming

https://medium.com/@GumtreeDevTeam/reactive-programming-hype-or-truth-e6fba44ace76

https://spring.io/blog/2016/06/07/notes-on-reactive-programming-part-i-the-reactive-landscape