Upload
martin-lehmann
View
368
Download
1
Embed Size (px)
Citation preview
1
Schnell reagiert! Reaktive Systeme auf der Java-Plattform mit Vert.x und Reactor
Martin Lehmann, Accso GmbH – Java Forum Stuttgart 2015
3
Diplom-Informatiker
Seit 2010 Mitglied der Geschäftsleitung und CTO bei der Accso – Accelerated Solutions GmbH in Darmstadtwww.accso.de
Seit Ende der 90er Jahre in Projekten für Individualentwicklung, v.a. als Technischer Architekt und Berater
Schwerpunkte: Java, SW-Architektur, Entwicklungsmethodik, Verteilte Systeme
Aktive Mitarbeit im iSAQB
jfs2015:~ # who am i
4 Copyright © Accso GmbH
Reaktive Systeme
Vert.x und Demo
Reactor Framework
Reactive Streams
Fazit
Reaktive Systeme
5 Copyright © Accso GmbH
Anforderungen an Performance:
Geringe Antwortzeiten, minimale Latenz, hoher Durchsatz
Anforderungen an Skalierbarkeit:steigende Nutzerzahlen, Multi-Core
Anforderungen an Verfügbarkeit:24x7, Failover, hohe Fehlertoleranz
Was sind die Anforderungen?
Forderungen des Reactive Manifesto: Responsive, Resilient, Elastic, Message-Driven
Event-basiertViele parallele
Requests Viele Abnehmer Pipelining,
Verarbeitungsketten
7 Copyright © Accso GmbH
Wetterdaten aus aller Welt
VerteilungAggregationArchivierungMonitoring
Archiv
8 Copyright © Accso GmbH
Aktoren-Modell
Nebenläufigkeitsprogrammierung mit Low-Level-APIs ist komplex: Kompliziert und damit fehleranfällig!
ReactorPattern
Weitere Anforderung: Beherrschbarkeit der Komplexität
„Altbekannte“ Nebenläufigkeitsprogrammierung nutzt i.d.R. Ressourcen nicht optimal aus.
LMAX Disruptor
9 Copyright © Accso GmbH
Aktorenmodell Carl Hewitt, 1973
Modell für nebenläufige Programmierung
Aktoren sind die ausführbaren Einheiten im System
Shared-Nothing-Architektur (kein globaler Zustand)
Kommunikation nur über asynchrones Messaging
Aktor
Aktor
Aktor
State
State
State
10 Copyright © Accso GmbH
Design Pattern für Event-Handling
Reactor = Dispatcher (von Events an Callback-Handler)
Entkoppelt Applikationslogik von Ausführungslogik
Reactor Pattern: Ausführung auf 1 Event-Loop-Thread
Multi-Reactor Pattern: Skalierung auf n ELTs
Handler müssen Blockierung des ELT vermeiden!
(Multi-)Reactor Pattern Douglas Schmidt u.a., 1996f
Client
Client
Client
Event
Loop
11 Copyright © Accso GmbH
(Multi-)Reactor Pattern Douglas Schmidt u.a., 1996f
loop {// you control the flowdoSomething();
}
registerHandler(doSomething);
loop {// event loop controls the flow// calls registered callbackevent = getEventFromEventQueue();dispatch(event);
}
Event Driven
Normal
13 Copyright © Accso GmbH
Reaktive Systeme
Vert.x und Demo
Reactor Framework
Reactive Streams
Fazit
Vert.x und Demo
http://vertx.io/
14 Copyright © Accso GmbH
Vert.x im Überblick
JVM 2.1.5 (und 3) modular
Laufzeit-Umgebung
nicht-blockierend
Message-Bus
polyglott
nebenläufig
single-threadedLaufzeitmodell
Programmiermodell
Open-Source
15 Copyright © Accso GmbH
Vert.x ClusterVert.x Laufzeitumgebung Vert.x Laufzeitumgebung
Vert.x Modul
Event-Bus
VerticleVerticleVerticleA
VerticleVerticleVerticleVerticleB
VerticleVerticleA
VerticleVerticleVerticleC
Shared Data Shared Data
Event Loop ThreadsEvent Loop Threads
Browser
Java-script
SockJS
Clustering(Hazelcast)
Clustering(Hazelcast)
Die Baustein-Architektur von Vert.x
16 Copyright © Accso GmbH
Die Laufzeit-Architektur von Vert.x
Vert.x Laufzeitumgebung
Event Loop Thread 1
Event Loop Thread 2
Event Loop Thread 3
Event Loop Thread 4
Zeit
Verticle A Verticle B Verticle A
Verticle C Verticle D
Verticle E Verticle F Verticle F
Verticle G Verticle H
17 Copyright © Accso GmbH
Die Laufzeit-Architektur von Vert.x
Vert.x Laufzeitumgebung
Event Loop Thread 1
Event Loop Thread 2
Event Loop Thread 3
Event Loop Thread 4
Zeit
Verticle A Verticle B Verticle A
Verticle C Verticle D
Verticle E Verticle F Verticle F
Verticle G Verticle H
Verticles werden immer auf demselben ELT ausgeführt!
Keine parallele Ausführung!Programmiermodell = single-threaded
Blockierung vermeiden! Wenn G blockiert, verhungert H!Langläufige und
blockierende Operationen in spezielle Worker-Verticles auslagern! (separater Thread-Pool)
Jedes Verticle hat eigenen Classloader. Kein Shared State!
public class HelloWorldHttpServer extends Verticle {
@Overridepublic void start() {
vertx.createHttpServer().requestHandler( (HttpServerRequest req) -> {
logInfoString(" received request " + req.remoteAddress() +" for " + req.path());
req.response().putHeader("content-type", "text/plain").end("Hello JFS!");
}).listen(8123);
logInfoString("registered HTTP server on port 8123");}
public class PongVerticle extends Verticle {@Overridepublic void start() {
Handler<Message<String>> handler = new Handler<Message<String>>() {public void handle(Message<String> message) {
logInfoString(" receives message " + message.body());vertx.eventBus().send(BUS_ADDRESS_PONG, "pong");
}};
// Obiger Handler wird fuer "Ping"-Nachrichten registriertvertx.eventBus().registerHandler(BUS_ADDRESS_PING, handler);logInfoString("PongVerticle has been registered for " + BUS_ADDRESS_PING);
}
public class PingVerticle extends Verticle {@Overridepublic void start() {
Handler<Message<String>> handler = new Handler<Message<String>>() {public void handle(Message<String> message) {
logInfoString(" receives message " + message.body());Handler<Message<String>> replyHandler = this;
// erneuten Ping verzoegert nach 1sec rausschickenvertx.setTimer(1000, new Handler<Long>() {public void handle(Long event) {
vertx.eventBus().send(BUS_ADDRESS_PING, "ping", replyHandler);}
});}
};
// Obiger Handler wird fuer "Pong"-Replys registriertvertx.eventBus().registerHandler(BUS_ADDRESS_PONG, handler);
// Bootstrap: Erste, initiale Nachricht an alle PongVerticles// Alle Pong-Verticles muessen vorher gestartet sein, sonst geht Nachricht verloren!vertx.eventBus().send(BUS_ADDRESS_PING, "ping", handler);
}
Demo
public class PingVerticle extends Verticle {@Overridepublic void start() {
Handler<Message<String>> handler = new Handler<Message<String>>() {public void handle(Message<String> message) {
logInfoString(" receives message " + message.body());
// erneuten Ping verzoegert nach 1sec rausschickenvertx.setTimer(1000, new Handler<Long>() {public void handle(Long event) {
vertx.eventBus().publish(BUS_ADDRESS_PING, "ping");}
});}
};
// Obiger Handler wird fuer "Pong"-Replys registriertvertx.eventBus().registerHandler(BUS_ADDRESS_PONG, handler);
// Bootstrap: Erste, initiale Nachricht an alle PongVerticles// Alle Pong-Verticles muessen vorher gestartet sein, sonst geht Nachricht verloren!vertx.eventBus().publish(BUS_ADDRESS_PING, "ping");
}
25 Copyright © Accso GmbH
Ganz frisch! Vert.x 3.0 24. Juni 2015
Verticles sind nun (potentiell) verzichtbar
Modulsystem ist umgebaut
Trennung in Core und Web
Asynchrone DB-Zugriffe (JDBC, MongoDB, …)
Integration von Mail, JCA, Cloud, Docker, …
Authentifizierung und Autorisierung
Neues Unit-Test-Framework
Metriken
Cluster-Manager austauschbar
Bus-Serialisierung austauschbar
Reactive: Rx und Reactive Streams
3.0
Erst mit 3.1
26 Copyright © Accso GmbH
Reaktive Systeme
Vert.x und Demo
Reactor Framework
Reactive Streams
Fazit
Reactor Framework
https://github.com/reactor/reactor
27 Copyright © Accso GmbH
JVM 2.0.3
Keine Laufzeit-Umgebung
Beeinflusst durch: Reactor Pattern, Java 8 Streams
Open-Source
Reactor-Framework im Überblick
polyglott
Optimiert auf Performance u. Durchsatz
… foundational library for reactive fast data
applications
28 Copyright © Accso GmbH
Kern des Reactor-Frameworks: Asynchroner Event-Bus
Reactor
Nimmt Events von Produzenten entgegen
Heisst Event-Busab Version 2
Dispatcher
Scheduling und Routing von Events
Nutzt Thread-Pool, Ringbuffer, je nach Konfiguration
Selector
Bestimmt die Adressaten eines Events
Adressierung über Strings, Objekttyp, Regulären Ausdruck, …
Consumer
Verarbeitet Events
Bus-API oder alternativ Stream-API
Reactor Framework: Stream-API
// InitCountDownLatch latch = new CountDownLatch(10);Environment.initialize();Broadcaster<String> stream = Streams.broadcast(Environment.get());
// Consumerstream.map(String::toUpperCase)
.consume(s -> {System.out.printf("Received %s on thread %s%n", s, Thread.currentThread());latch.countDown();
});
// Publisherfor (int i=0; i<10; i++) {
String message = "hello world " + i;System.out.printf("Sending %s on thread %s%n", message, Thread.currentThread());stream.onNext(message);
}stream.onComplete();
// shutdownlatch.await()Environment.terminate();
31 Copyright © Accso GmbH
Reaktive Systeme
Vert.x und Demo
Reactor Framework
Reactive Streams
Fazit
Reactive StreamsRxJava
Ratpack
32 Copyright © Accso GmbH
Mit Reactive Streams aus der Callback-Hölle
Problem 1: Callback-Hölle
public class PingVerticle extends Verticle {@Overridepublic void start() {
Handler<Message<String>> handler = new Handler<Message<String>>() {public void handle(Message<String> message) {
vertx.setTimer(1000, new Handler<Long>() {public void handle(Long event) {
... }
});}
};
33 Copyright © Accso GmbH
Sender und Empfänger müssen zusammenarbeiten
Sender Empfänger
Problem 2: Unterschiedliche Verarbeitungsgeschwindigkeiten
34 Copyright © Accso GmbH
Sender und Empfänger müssen zusammenarbeiten
Sender Empfänger
Problem 2: Unterschiedliche Verarbeitungsgeschwindigkeiten
35 Copyright © Accso GmbH
Reactive Streams: Spezifikation von Schnittstellen
Publisher Subscriber
Publish-Subscribe-Modell (nur JVM-intern, nicht -übergreifend)
Subscribe (n Datenpakete)
Umgang mit Backpressure im Publisher:Puffern, Verwerfen, Backpressure weiterreichen nach „Upstream“
37 Copyright © Accso GmbH
Reaktive Systeme
Vert.x und Demo
Reactor Framework
Reactive Streams
FazitFazit
38 Copyright © Accso GmbH
Zum Nachlesen
JavaSPEKTRUM 5/2014
Dr. Rüdiger Grammes, Martin Lehmann, Dr. Kristine Schaal
Gut verknotet - Vert.x im Einsatz für hochskalierbare Architekturen
PDF: http://goo.gl/j4zyb0
Dr. Rüdiger Grammes, Martin Lehmann, Dr. Kristine Schaal
Reaktive Anwendungen mit dem Reactor-Framework
http://heise.de/-2405139
39
Begeisterung für dieanspruchsvollen Aufgaben unserer Kunden
Accso – Accelerated Solutions GmbHwww.accso.detwitter.com/accso
Berliner Allee 5864295 DarmstadtTelefon: +49 (6151) 13029-0Fax: +49 (6151) 13029-10
Moltkestraße 131 a50674 KölnTelefon: +49 (221) 630691-0Fax: +49 (221) 630691-10
Theatinerstraße 1180333 MünchenTelefon: +49 (89) 71042-2040Fax: + 49 (89) 71042-2001