2. WHO AM I?
• Sebastian Springer
• aus München
• arbeite bei Mayflower
• https://github.com/sspringer82
• @basti_springer
• Consultant,Trainer,Autor
3. Bei der Datenverarbeitung ist Reaktive Programmierung ein
Programmierparadigma, das sich an Datenflüssen orientiert. In den
zugeordneten Programmiersprachen sind statische oder dynamische
Datenflüsse leicht auszudrücken. Das zugrunde liegende
Ausführungsmodell propagiert Änderungen in den Datenflüssen
automatisch.
Wikipedia meint:
16. Mit Angular lassen sich die Datenflüsse im Frontend
modellieren. Mit dem Two-way Data Binding werden die
Änderungen automatisch propagiert.
Aber nur auf Clientseite.
18. Anforderungen
Es gibt mehr als einen Client. Jeder verbundene Client darf
Informationen lesen, erstellen, ändern und löschen.
Alle Clients müssen über Änderungen benachrichtigt werden
bzw. die Änderungen müssen automatisch propagiert werden.
HTTP ist unidirektional - also brauchen wir eine Alternative.
25. Konflikt
Greifen mehrere Benutzer auf einen Datensatz schreibend
zu (editieren oder löschen), kommt es zu einem Konflikt.
Die einfachste Lösung lautet: Derjenige, der zuletzt schreibt,
gewinnt.
26. Konflikt
Eine weitere Lösung liegt im Sperren von Datensätzen.
Bearbeiten/Löschen-Funktionen werden per Websocket-
Nachricht deaktivert und erst aktiviert, wenn die Daten
geändert sind.
27. Konflikt
Konflikte können auch automatisch aufgelöst werden. Git
macht es beispielsweise bei Merges so. Solche Operationen
sind allerdings meistens sehr komplex.
31. Responsive
Schnelle und direkte Rückmeldung. Usability ist gegeben.
Der Benutzer weiß zu jedem Zeitpunkt, was die Applikation
tut.
Fehler werden schnell bemerkt und der Benutzer darüber in
Kenntnis gesetzt.
Responsiveness hat nichts mit dem Responsive Layout zu tun!
35. Responsive
Am besten sollte der Benutzer überhaupt nicht warten
müssen. Also prefetching, caching und ähnliches nutzen.
Wenn gespeichert wird, abschicken, Anfrage wird bearbeitet
und weitermachen lassen. Bei Fehlern, Benutzer später
informieren.
37. Resilient
Das System muss robust sein. Ein Fehler darf nicht dazu
führen, dass das gesamte System nicht mehr funktionsfähig
ist.
38.
39. Resilient - Subsysteme
Das System besteht aus einer Vielzahl von möglichst
unabhängigen Subsystemen.
Funktioniert ein Subsystem nicht, muss das übrige System
trotzdem funktionsfähig sein.
40. Resilient - Fehlerbehandlung
Auf Error-Events reagieren. Fehlerobjekte in Callback-
Funktionen beachten. Try-Catch-Blöcke einbauen, hier auf
asynchrone Funktionen achten. Den Benutzer über einen
Fehler in Kenntnis setzen und die Situation möglichst
korrigieren.
Fehler möglichst protokollieren.
41. Resilient - Backend
Prozesse im Fehlerfall neu starten. Aber Vorsicht vor
Endlosschleifen.
Logging von Fehlern, Nachrichten an Admins versenden (E-
Mail, SMS, Jabber).
Failover - der Loadbalancer schickt Benutzer bei einem
Ausfall an andere Systeme.
43. Elastic
Das System kann mit unterschiedlichen Lastverhältnissen
umgehen. Die Antwortzeiten werden auch durch viele
Zugriffe nicht negativ beeinflusst.
44. Wie man es nicht macht:
Die Applikation kann zwischen 9:00 Uhr und 11:00 Uhr nicht
verwendet werden, weil zu viele Benutzer die Dienste nutzen.
Der eine(!) Datenbankserver ist ausgefallen - nix geht mehr.
45. Elastic - Node
Node ist Single-Threaded. Blockierende Routinen bringen
die komplette Applikation zum Stehen.
Das child_process- und cluster-Modul schaffen Abhilfe,
indem sie Kindprozesse erzeugen und die Arbeit verteilen.
Mehr Kindprozesse als Prozessorkerne bringen in den
seltensten Fällen einen Mehrwert.
46. Elastic - System
Jede Komponente sollte mehrfach vorhanden sein.
Mehrere Backend-Knoten hinter einem Loadbalancer (z.B.
Nginx).
Auch Websocket-Verbindungen können durch den
Loadbalancer verteilt werden.
Datenbanksysteme durch Cluster ausfallsicher halten.
Bei Bedarf können zusätzliche Systeme zugeschaltet werden.
48. Message Driven
Entkopplung der Systemkomponenten. Senden von
Nachrichten und asynchrone Behandlung. Mehrere
Subsysteme können eine Nachricht unabhängig voneinander
empfangen. Ziel ist eine nicht-blockierende Abarbeitung.
Einsatz von Message Queues zur kontrollierten Abarbeitung
von Nachrichten.
49. Wie man es nicht macht:
var fs = require('fs');
var content = fs.readFileSync('./currencies.csv', 'utf-8');
50. Message Driven
Eigentlich basiert das komplette System schon auf dem Fluss
von Nachrichten. Sowohl das Frontend als auch die
Kommunikation über Websockets und das Backend in
Node.js basieren auf Ereignissen und deren asynchroner
Behandlung.
Man muss es nur richtig einsetzen.
51. Reactive
Entkoppelt - Einzelne Subsysteme können ausgetauscht
werden.
Flexibel - Systeme können gut auf geänderte Anforderungen
reagieren.
Skalierbar - Das System kann mit mehr Last umgehen.
Interaktiv - Der Benutzer weiß zu jeder Zeit, wo er steht und
was das System macht.