Slide 1

Slide 1 text

Applications réactives avec Eclipse Vert.x Paris JUG

Slide 2

Slide 2 text

Julien Viet Open source developer for 15+ years Current @vertx_project lead Principal software engineer at Marseille Java User Group Leader https://www.julienviet.com/ http://github.com/vietj @julienviet  https://www.mixcloud.com/cooperdbi/

Slide 3

Slide 3 text

Outline ✓ Reactive? Vert.x? ✓ Foundations ✓ High performance networking ✓ Ecosystem

Slide 4

Slide 4 text

Reactive? Vert.x?

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

Application

Slide 7

Slide 7 text

Software Messages Requests Metrics Availability

Slide 8

Slide 8 text

Reactive systems Reactive streams Reactive programming Reactive “Responding to stimuli” Manifesto, Actor, Messages Resilience, Elasticity, Scalability, Asynchronous, non-blocking Data flow Back-pressure Non-blocking Data flow Events, Observable Spreadsheets Akka, Vert.x Akka Streams, Rx v2, Reactor, Vert.x Reactor, Reactive Spring, RxJava, Vert.x

Slide 9

Slide 9 text

Eclipse Vert.x Open source project started in 2012 Eclipse / Apache licensing A toolkit for building reactive applications for the JVM 7K ⋆ on Built on top of https://vertx.io @vertx_project

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

Reactive foundations

Slide 12

Slide 12 text

Reactive foundations ✓ Concurrency model ✓ Scalability model

Slide 13

Slide 13 text

while (isRunning) { String line = bufferedReader.readLine(); switch (line.substring(0, 4)) { case "ECHO": bufferedWriter.write(line); break !// !!... !// other cases (!!...) !// !!... default: bufferedWriter.write("Unknown command"); } }

Slide 14

Slide 14 text

x 1000 = Ǚ

Slide 15

Slide 15 text

C1 “When you have a line of text, call C2” Something else with no blocking call either C2

Slide 16

Slide 16 text

Events Thread Event Loop

Slide 17

Slide 17 text

 2 event-loops per CPU core by default

Slide 18

Slide 18 text

Vertx vertx = Vertx.vertx(); // Create a Vert.x context associated with an event loop Context context = vertx.getOrCreateContext(); // Execute a task on the event loop context.runOnContext(v -> { // Create an HTTP server running on this context’s event loop HttpServer server = vertx.createHttpServer(); server.requestHandler(request -> { request.response().end("Hello World"); }).listen(8080); }); System.in.read(); // Close all resources vertx.close();

Slide 19

Slide 19 text

 Verticles public class HttpVerticle extends AbstractVerticle { public static void main(String[] args) { Vertx vertx = Vertx.vertx(); vertx.deployVerticle(Server.class.getName()); System.in.read(); vertx.close(); } @Override public void init(Vertx vertx, Context context) { // Associates this verticle with // its deployment context super.init(vertx, context); } @Override public void start() throws Exception { HttpServer server = vertx.createHttpServer(); server.requestHandler(request -> { request .response() .end("Hello World"); }).listen(8080); } }

Slide 20

Slide 20 text

Configuration Network events come from event loop threads Verticle Deploy Deploy

Slide 21

Slide 21 text

Simplified concurrency model public class ChatVerticle extends AbstractVerticle { private Set webSockets = new HashSet<>(); @Override public void start() throws Exception { HttpServer server = vertx.createHttpServer(); server.websocketHandler(webSocket -> { webSocket.textMessageHandler(msg -> { webSockets.forEach(other -> other.writeTextMessage(msg)); }); webSocket.closeHandler(v -> webSockets.remove(webSocket)); webSockets.add(webSocket); }).listen(8080); } }

Slide 22

Slide 22 text

Worker thread pool Blocking task executeBlocking Result

Slide 23

Slide 23 text

“Regular verticle” (same event event-loop thread) Worker verticle (1 worker thread) Multi-thread worker verticle Worker pool

Slide 24

Slide 24 text

Deployment model Vertx vertx = Vertx.vertx(); vertx.deployVerticle(HttpVerticle.class.getName(), new DeploymentOptions() .setInstances(3)); Deploys 3 instances 3 event loop 1. bind the port 2. add event loop 3. add event loop

Slide 25

Slide 25 text

No content

Slide 26

Slide 26 text

Deployment model Vertx vertx = Vertx.vertx(); // Deploy 5 instances on 5 event loops vertx.deployVerticle(HttpVerticle.class.getName(), new DeploymentOptions() .setInstances(5)); // The database verticle uses // deploy 2 instances on 2 event loops vertx.deployVerticle(DatabaseVerticle.class.getName(), new DeploymentOptions() .setInstances(2));

Slide 27

Slide 27 text

High performance networking

Slide 28

Slide 28 text

Performance ✓ Building bottom up ✓ Non blocking IO ✓ Reactive back-pressure

Slide 29

Slide 29 text

Pay the right price ✓ Tiny footprint ✓ Do one thing and do it well ✓ Does not solve other (non) problems such as classloading or IoC ✓ Modular set of extensions

Slide 30

Slide 30 text

Non-blocking IO benefits ✓ Handle many connections with a few threads - focus on protocol concurrency - minimize system calls - more efficient for pipelined/multiplexed protocols

Slide 31

Slide 31 text

Non-blocking IO benefits ✓ Get away from thread pools - removes unnecessary bottlenecks - easier capacity planning - focus on protocol concurrency

Slide 32

Slide 32 text

Non-blocking IO benefits ✓ Gracefully handle slow connection - remain responsive - don’t impact other connections

Slide 33

Slide 33 text

Networking/messaging with Vert.x ✓ Vert.x Core - TCP, HTTP/1, HTTP/2, WebSocket, UDP, DNS ✓ Vert.x Web - SockJS ✓ MQTT ✓ AMQP ✓ gRPC

Slide 34

Slide 34 text

Typical HTTP server MongoClient client = MongoClient.createNonShared(vertx, getConfig());
 HttpServer server = vertx.createHttpServer(); 
 server.requestHandler(request -> {
 if (request.path().equals("/document")) {
 client.findOne("docs", QUERY, fieldsOf(request), ar -> {
 if (ar.succeeded()) {
 String json = ar.result().encode();
 request.response().end(json);
 } else {
 request.response().setStatusCode(500).end();
 }
 });
 } else { /* … */ }
 });
 
 server.listen(8080);

Slide 35

Slide 35 text

Blocking server Backend Workers

Slide 36

Slide 36 text

Blocking server Backend Workers

Slide 37

Slide 37 text

Blocking server Backend Workers

Slide 38

Slide 38 text

Blocking server Backend Workers

Slide 39

Slide 39 text

Blocking server Backend Workers

Slide 40

Slide 40 text

Blocking server Backend Workers

Slide 41

Slide 41 text

Blocking server Backend Workers

Slide 42

Slide 42 text

Non-blocking server Backend Event Loop Requests Responses

Slide 43

Slide 43 text

Non-blocking server Backend Event Loop Requests Responses

Slide 44

Slide 44 text

Non-blocking server Backend Event Loop Requests Responses

Slide 45

Slide 45 text

Non-blocking server Backend Event Loop Requests Responses

Slide 46

Slide 46 text

Non-blocking server Backend Event Loop Requests Responses

Slide 47

Slide 47 text

Non-blocking server Backend Event Loop Requests Responses

Slide 48

Slide 48 text

Message passing on the event bus

Slide 49

Slide 49 text

Http server verticle Database client verticle  ?

Slide 50

Slide 50 text

Http server verticle Database client verticle  Event Bus “Details for user 1234?” Send to “user.db” ×3 ×10

Slide 51

Slide 51 text

Http server verticle Database client verticle  Event Bus “Details for user 1234?” Send to “user.db” Consume from “user.db” ×3 ×10

Slide 52

Slide 52 text

Http server verticle Database client verticle  Event Bus “Details for user 1234?” “{data}” ×3 ×10

Slide 53

Slide 53 text

Asynchronous messaging “foo.bar”, “foo-bar”, “foo/bar”, … Point to point (with possible response back) Publish / subscribe

Slide 54

Slide 54 text

Distributed across Vert.x nodes Hazelcast, Ignite, Infinispan, … TCP bridge interface Go, Python, C, JavaScript, Swift, C#, … SockJS bridge Seamless frontend / backend messaging

Slide 55

Slide 55 text

Headers DeliveryOptions (e.g., timeouts) Body Address Reply address

Slide 56

Slide 56 text

“Primitive” types String, int, double, … JSON Object/Array Polyglot applications, clean boundaries Custom codecs For advanced usages

Slide 57

Slide 57 text

EventBus eb = vertx.eventBus(); eb.consumer("ping-address", message !-> { System.out.println("Received message: " + message.body()); message.reply("pong!"); }); EventBus eb = vertx.eventBus(); vertx.setPeriodic(1000, v !-> { eb.send("ping-address", "ping!", reply !-> { if (reply.succeeded()) { System.out.println("Received reply " + reply.result().body()); } else { System.out.println("No reply"); } }); });

Slide 58

Slide 58 text

Dealing with asynchronous events

Slide 59

Slide 59 text

Callbacks RxJava 1 + 2 Quasar (vertx-sync) Kotlin coroutines (core) (codegen) (codegen) (codegen) (codegen)

Slide 60

Slide 60 text

foo.a(1, res1 -> { if (res1.succeeded()) { bar.b("abc", 1, res2 -> { if (res.succeeded()) { baz.c(res3 -> { dosomething(res1, res2, res3, res4 -> { // (...) }); }); } }); } }); “Callback hell”

Slide 61

Slide 61 text

jdbc.rxGetConnection().flatMap(conn !-> { !// Now chain some statements using flatmap composition Single resa = conn.rxUpdate("CREATE TABLE test(col VARCHAR(20))") .flatMap(result !-> conn.rxUpdate("INSERT INTO test (col) VALUES ('val1')")) .flatMap(result !-> conn.rxUpdate("INSERT INTO test (col) VALUES ('val2')")) .flatMap(result !-> conn.rxQuery("SELECT * FROM test")); return resa.doAfterTerminate(conn!::close); }).subscribe(resultSet !-> { !// Subscribe to the final result System.out.println("Results : " + resultSet.getRows()); }, err !-> { System.out.println("Database problem"); err.printStackTrace(); });

Slide 62

Slide 62 text

try (SQLConnection conn = awaitResult(jdbc!::getConnection)) { !// Create a table Void v = awaitResult(h !-> conn.execute("CREATE TABLE test(col VARCHAR(20))", h)); !// Insert some stuff for (int i = 0; i < 10; i!++) { int ii = i; UpdateResult res = awaitResult(h !-> conn.update("INSERT INTO test (col) VALUES ('val" + ii + "')", h)); System.out.println("Rows updated: " + res.getUpdated()); } !// Select the results ResultSet res = awaitResult(h !-> conn.query("SELECT * FROM test", h)); System.out.println("Selected " + res.getNumRows() + " results"); res.getResults().forEach(System.out!::println); }

Slide 63

Slide 63 text

val consumer = vertx.eventBus().localConsumer("a.b.c") consumer.handler { message "-> println("Consumer received: ${message.body()}") message.reply("pong") } !// Wait until the consumer has properly registered asyncResult { h "-> consumer.completionHandler(h) } !// Send a message and wait for a reply val reply = asyncResult> { h "-> vertx.eventBus().send("a.b.c", "ping", h) } println("Reply received: ${reply.body()}")

Slide 64

Slide 64 text

Reactive Programming with Vert.x and RxJava

Slide 65

Slide 65 text

RxJava Data and events flows Organising transformation of data and coordination of events Makes most sense with many sources of events

Slide 66

Slide 66 text

Motivation Future> is not appropriate Dealing with latencies Functional programming influence

Slide 67

Slide 67 text

RxJava 1 vs RxJava 2 Better raw performances Based on reactive-streams Null values forbidden More reactive types Observable / Flowable Single / Maybe / Completable

Slide 68

Slide 68 text

Event push subscribe ➊ ➋push Observer Observable

Slide 69

Slide 69 text

Iterable / Observable try {
 for (String item : it) { ➊
 } ➌
 } catch (Throwable e) { ➋
 } observable.subscribe(item -> {
 ➊ // onNext
 }, error -> {
 ➋ // onError
 }, () -> {
 ➌ // onCompleted
 });

Slide 70

Slide 70 text

RxJava 1 types Reactive Completable Single Observable Interactive void Optional Iterable

Slide 71

Slide 71 text

RxJava 2 types Reactive Completable Maybe Single Observable Interactive void Optional T Iterable

Slide 72

Slide 72 text

No content

Slide 73

Slide 73 text

No content

Slide 74

Slide 74 text

No content

Slide 75

Slide 75 text

No content

Slide 76

Slide 76 text

Rxified APIs Each API type (annotated with @VertxGen) has its prefix io.vertx replaced by io.vertx.rxjava io.vertx.core.Vertx io.vertx.rxjava.Vertx etc…

Slide 77

Slide 77 text

Rxified Handler void listen(int port, Handler> ar)
 
 Single rxListen(int port);

Slide 78

Slide 78 text

(demo) RxJava

Slide 79

Slide 79 text

Outro

Slide 80

Slide 80 text

Vert.x Awesome Vert.x Stack Vert.x Core

Slide 81

Slide 81 text

Unified end-to-end reactive model + ecosystem (not just APIs…) For all kinds of distributed applications (even the small-scale ones) Flexible toolkit, not a framework (your needs, your call)

Slide 82

Slide 82 text

https:!//youtu.be/ZkWsilpiSqw Applications réactives avec Eclipse Vert.x Building Reactive Microservices in Java https:!//goo.gl/ep6yB9 https:!//youtu.be/ApGNp4uHKdY Microservices réactifs avec Eclipse Vert.x et Kubernetes Guide to async programming with Vert.x for Java developers https:!//goo.gl/AcWW3A