Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Applications réactives avec Eclipse Vert.x

Julien Viet
December 13, 2017
190

Applications réactives avec Eclipse Vert.x

Julien Viet

December 13, 2017
Tweet

Transcript

  1. 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/
  2. 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
  3. 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
  4. while (isRunning) { String line = bufferedReader.readLine(); switch (line.substring(0, 4))

    { case "ECHO": bufferedWriter.write(line); break !// !!... !// other cases (!!...) !// !!... default: bufferedWriter.write("Unknown command"); } }
  5. C1 “When you have a line of text, call C2”

    Something else with no blocking call either C2
  6. 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();
  7.  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); } }
  8. Simplified concurrency model public class ChatVerticle extends AbstractVerticle { private

    Set<ServerWebSocket> 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); } }
  9. 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));
  10. 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
  11. Non-blocking IO benefits ✓ Handle many connections with a few

    threads - focus on protocol concurrency - minimize system calls - more efficient for pipelined/multiplexed protocols
  12. Non-blocking IO benefits ✓ Get away from thread pools -

    removes unnecessary bottlenecks - easier capacity planning - focus on protocol concurrency
  13. Non-blocking IO benefits ✓ Gracefully handle slow connection - remain

    responsive - don’t impact other connections
  14. Networking/messaging with Vert.x ✓ Vert.x Core - TCP, HTTP/1, HTTP/2,

    WebSocket, UDP, DNS ✓ Vert.x Web - SockJS ✓ MQTT ✓ AMQP ✓ gRPC
  15. 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);
  16. Http server verticle Database client verticle  Event Bus “Details

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

    for user 1234?” Send to “user.db” Consume from “user.db” ×3 ×10
  18. Distributed across Vert.x nodes Hazelcast, Ignite, Infinispan, … TCP bridge

    interface Go, Python, C, JavaScript, Swift, C#, … SockJS bridge Seamless frontend / backend messaging
  19. 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"); } }); });
  20. 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”
  21. jdbc.rxGetConnection().flatMap(conn !-> { !// Now chain some statements using flatmap

    composition Single<ResultSet> 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(); });
  22. 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); }
  23. val consumer = vertx.eventBus().localConsumer<String>("a.b.c") consumer.handler { message "-> println("Consumer received:

    ${message.body()}") message.reply("pong") } !// Wait until the consumer has properly registered asyncResult<Void> { h "-> consumer.completionHandler(h) } !// Send a message and wait for a reply val reply = asyncResult<Message<String!>> { h "-> vertx.eventBus().send("a.b.c", "ping", h) } println("Reply received: ${reply.body()}")
  24. RxJava Data and events flows Organising transformation of data and

    coordination of events Makes most sense with many sources of events
  25. RxJava 1 vs RxJava 2 Better raw performances Based on

    reactive-streams Null values forbidden More reactive types Observable / Flowable Single / Maybe / Completable
  26. Iterable / Observable try {
 for (String item : it)

    { ➊
 } ➌
 } catch (Throwable e) { ➋
 } observable.subscribe(item -> {
 ➊ // onNext
 }, error -> {
 ➋ // onError
 }, () -> {
 ➌ // onCompleted
 });
  27. 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…
  28. 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)
  29. 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