vert.x 3

42
Vert.x 3 high performance polyglot application toolkit

Upload: xavier-marin

Post on 14-Apr-2017

1.048 views

Category:

Internet


1 download

TRANSCRIPT

Page 1: Vert.x 3

Vert.x 3high performance polyglot application toolkit

Page 2: Vert.x 3

Xavier MARIN

@XavMarinhttps://github.com/Giwi

Architecte chez @cmarkeaCTO chez @qaobee

Page 3: Vert.x 3

Petite histoire

● Créé par Tim Fox @timfox ● en 2011 chez VMWare● sous le nom de Node.x● 2012 : devient Vert.X● 2013 : passe dans la fondation Eclipse● 24/06/2015 sortie de la v3● environ 180 contributeurs

https://www.parleys.com/search/vert.x/PRESENTATIONS

Page 4: Vert.x 3

Vocabulaire pour commerciaux

Simple threadSafe concurrent

asynchronous eventDriven reactive

eventBus over a scalable polyglot

embeddable toolkit plateform

Page 5: Vert.x 3

Le problème

● Répondre à un grand nombre de clients en même temps

● C10k = 10 000 connexions simultanées

Page 6: Vert.x 3

C10k

Page 7: Vert.x 3

C10k

Page 8: Vert.x 3

C10k

Page 9: Vert.x 3

C10k

Page 10: Vert.x 3

C10k

Tomcat : 200 threads = 200 connexionsLes appels suivants doivent attendre

Page 11: Vert.x 3

C10k

● Scalable verticalement et horizontalement● Distribué● Événementiel et asynchrone● I/O non bloquantes● Tolérant à la panne● Extensible

Page 12: Vert.x 3

Fonctionnalités

Le déploiement :

● Compilation à la volée du source : Java, Groovy, etc...

● Trouve les ressources en local ou dans un repo maven

● CLI / main(String[] args) / Maven / Gradle ● Classloader :Isolation par classloader

optionnelle

Page 13: Vert.x 3

Fonctionnalités

La stack native :

● Vert.x core● Vert.x Web

○ Routages et sous-routages○ Sessions○ Cookies○ Sécurité (basic auth, shiro, JWT, …)○ Templates (Handlebars, Jade, MVEL, Thymeleaf)○ SockJS○ Static files○ …

Page 14: Vert.x 3

Fonctionnalités

● Accès aux données○ MongoDB, JDBC, Redis, SQL Common

● Intégration○ Mail et JCA

● Sécurité○ basic auth, shiro, JWT, JDBC Auth

● Reactive○ Vert.X Rx, Reactive streams

● Metrics● Vert.X unit

Page 15: Vert.x 3

Fonctionnalités

● Clients / Serveurs TCP/SSL● Clients / Serveurs HTTP/HTTPS● REST et Multipart● Websockets et Sock.js● Accès distribué de l'Event-bus● Maps et Sets partagés● Logging

Page 16: Vert.x 3

Nouveautés Vert.x 3

● Les API Vert.x 2 sont maintenues à la main ● Vert.x 3 peut générer des API

○ Codegen○ Basé sur des templates MVEL

● JavaScript, Groovy, RxJava – Ruby à venir, etc ...

● Maintenance automatique● Les API de la stack entière sont générées● Documentation polyglotte

Page 17: Vert.x 3

Nouveautés Vert.x 3

● L’API Core reste fondamentalement identique

● Supprime les inconvénients de Vert.x 2● Déploiement de services ● Support de Java8

○ streams et lamdas (yummi yummi !)● Support de RxJava, RxGroovy, RxJS ● Une stack “supportée” : composant *

langage

Page 18: Vert.x 3

JVM polyglotte

Dois-je coder en java pour exécuter un programme sur la JVM?

Oui, mais pas que, fais-toi plaisir!

Page 19: Vert.x 3

JVM polyglotte

On peut programmer en plus de 200 langages

Java, JavaFX, Ceylon, Gosu, Groovy, Clojure, Rhino Nashorn, Mirah, Scala, JRuby, Xtend, JPython, Fantom, Oxygene, Kotlin, …

L’intérêt : à chaque problème sa solution“Quand on n’a qu’un marteau dans la main, les vis

ressemblent à des clous”

Page 20: Vert.x 3

Polyglottevar vertx = require('vertx-js/vertx');

var server = vertx.createHttpServer(); var response = request.response(); response.putHeader('content-type', 'text/plain'); response.end('Hello World!');});

server.listen(8080);

$> vertx run server.js --instances 32$> java -jar my-app-fat.jar --instances 32

Page 21: Vert.x 3

Polyglotteserver = vertx.create_http_server()

server.request_handler() { |request| response = request.response() response.put_header("content-type", "text/plain") response.end("Hello World!")}

server.listen(8080)

$> vertx run server.rb --instances 32$> java -jar my-app-fat.jar --instances 32

Page 22: Vert.x 3

Polyglottedef server = vertx.createHttpServer()

server.requestHandler({ request -> def response = request.response() response.putHeader("content-type", "text/plain") response.end("Hello World!")})

server.listen(8080)

$> vertx run Server.groovy --instances 32$> java -jar my-app-fat.jar --instances 32

Page 23: Vert.x 3

Polyglottepublic class Main {

public static void main(String[] args) {

HttpServer server = vertx.createHttpServer(); server.requestHandler(request -> { HttpServerResponse response = request.response();

response.putHeader("content-type", "text/plain"); response.end("Hello World!"); }); server.listen(8080); }

}

$> vertx run Server.java --instances 32$> java -jar my-app-fat.jar --instances 32

Page 24: Vert.x 3

Cluster et haute disponibilité

Clustering$> java -jar my-app-fat.jar --instances 32 -cluster

Automatic failover● Quand un noeud tombe, ses verticles sont redéployés

sur les autres noeuds du cluster

$> vertx run my-app.js -cluster -ha

Page 25: Vert.x 3

Verticle

● Unité de déploiement de base● Modèle Actor● S’exécute toujours dans le même thread● Peut avoir plusieurs instances● Isolé dans son classLoader● Communique via l’event-bus● Peut se partager des données

○ maps○ counters○ locks

Page 26: Vert.x 3

VerticleJsonObject config = config().getObject("verticle_conf");

// Start the verticles that make up the app

vertx.deployVerticle("verticle1.js");

DeploymentOptions options = new DeploymentOptions().setInstances(16);vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", options);

DeploymentOptions options2 = new DeploymentOptions().setConfig(config);

vertx.deployVerticle("verticle2.rb", options2);

vertx.deployVerticle("com.mycompany.MyOrderProcessorVerticle", res -> {

if (res.succeeded()) {

System.out.println("Deployment id is: " + res.result());

} else {

System.out.println("Deployment failed!");

}

});

Page 27: Vert.x 3

Event-bus

Page 28: Vert.x 3

Event-bus

● Permet aux Verticles de communiquer● Agnostique du langage utilisé● Fonctionne à travers le cluster● S'étend jusqu'à la partie client (Js, Android, iOS)

● Types de messages○ number○ string○ boolean○ JSON object○ Vert.x Buffer

Page 29: Vert.x 3

Event-bus

● Enregistrer un handler● Dé-référencer un handler● Adresses● Messages

○ Publish / subscribe○ Point à point

Page 30: Vert.x 3

Event-bus

Enregistrer un handler

EventBus eb = vertx.eventBus();eb.consumer("news.uk.sport", message -> {

System.out.println("I have received a message: " + message.body());

message.reply("how interesting!");});

Page 31: Vert.x 3

Event-bus

Enregistrer un handlerMessageConsumer<String> consumer = eb.consumer("news.uk.sport");consumer.completionHandler(res -> { if (res.succeeded()) { System.out.println("Registration has reached all nodes"); } else { System.out.println("Registration failed!"); }});

consumer.unregister(res -> { if (res.succeeded()) { System.out.println("Un-registration has reached all nodes"); } else { System.out.println("Un-registration failed!"); }});

Page 32: Vert.x 3

Event-bus

Publish Subscribe :eventBus.publish("news.uk.sport", "You kicked a ball");

Point à point :eventBus.send("news.uk.sport","You kicked a ball",ar ->{ if (ar.succeeded()) { System.out.println("reply: " + ar.result().body()); }});

Ajout d'en-têteDeliveryOptions options = new DeliveryOptions();options.addHeader("some-header", "some-value");eventBus.send("news.uk.sport", "You kicked a ball",

options);

Page 33: Vert.x 3

Module Web

Le routeur :

Route route = router.route(HttpMethod.PUT, "myapi/orders") .consumes("application/json") .produces("application/json");

route.handler(routingContext -> {

// This would be match for any PUT method to paths starting with

// "myapi/orders" with a content-type of "application/json" // and an accept header matching "application/json"

});

Page 34: Vert.x 3

Module Web

Le routeur : Router restAPI = Router.router(vertx);restAPI.get("/products/:productID").handler(rc -> { // TODO Handle the lookup of the product.... rc.response().write(productJSON);});restAPI.put("/products/:productID").handler(rc -> { // TODO Add a new product... rc.response().end();});Router mainRouter = Router.router(vertx);// Handle static resourcesmainRouter.route("/static/*").handler(StaticHandler.create());mainRouter.route(".*\\.templ").handler(myTemplateHandler);mainRouter.mountSubRouter("/productsAPI", restAPI);

$curl http://localhost:8080/productsAPI/products/product/1234

Page 35: Vert.x 3

Module Web

Le routeur : router.route().path("/*")

.consumes("application/json")

.handler(routingContext -> {HttpServerResponse response = routingContext.response();response.putHeader("content-type", "application/json");routingContext.next();

});

router.get("/beers/").handler(routingContext -> {JsonObject query = new JsonObject();mongoClient.find("beers", query, res -> {

if (res.succeeded()) {JsonArray jar = new JsonArray();res.result().forEach(jar::add);routingContext.response().end(jar.encodePrettily());

} else { res.cause().printStackTrace(); } });}

Page 36: Vert.x 3

Benchmarks

Source : http://www.cubrid.org

Page 37: Vert.x 3

Benchmarks

Source : https://www.techempower.com/benchmarks/#section=data-r8&hw=i7&test=plaintext

Page 38: Vert.x 3

Cloud ready

● Vert.x OpenShift Cartridge○ https://github.com/vert-x3/vertx-openshift-cartridge

● Vert.x OpenShift Using DIY Cartridge○ https://github.com/vert-x3/vertx-openshift-diy-quickstart

● Vert.x Docker Images○ https://github.com/vert-x3/vertx-stack/tree/master/stack-docker

Page 39: Vert.x 3

Production ready

Page 40: Vert.x 3

Bonus

Si vous aimez vraiment Tomcat :

Exposer une API REST : http://sparkjava.comimport static spark.Spark.*;

public class HelloWorld { public static void main(String[] args) { get("/hello", (req, res) -> "Hello World"); }}

Page 41: Vert.x 3

Bonus

Si vous aimez vraiment Tomcat :

Consommer une API REST : http://unirest.ioHttpResponse<JsonNode> jsonResponse = Unirest.post("http://httpbin.org/post") .queryString("name", "Mark") .field("last", "Polo") .asJson();

Page 42: Vert.x 3

The end ...

« Si vous avez compris ce que je viens de vous dire, c’est que je me suis probablement mal exprimé »

A. Greenspan

https://github.com/Giwi/vertx3-angular-beers