Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare une entreprise Scribd logo
Vert.x 3
high performance polyglot application toolkit
Xavier MARIN
@XavMarin
https://github.com/Giwi
Architecte chez @cmarkea
CTO chez @qaobee
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
Vocabulaire pour commerciaux
Simple threadSafe
concurrent
asynchronous
eventDriven reactive
eventBus over a
scalable polyglot
embeddable toolkit
plateform
Le problème
● Répondre à un grand nombre de clients en
même temps
● C10k = 10 000 connexions simultanées
C10k
C10k
C10k
C10k
C10k
Tomcat : 200 threads = 200 connexions
Les appels suivants doivent attendre
C10k
● Scalable verticalement et horizontalement
● Distribué
● Événementiel et asynchrone
● I/O non bloquantes
● Tolérant à la panne
● Extensible
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
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
○ …
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
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
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
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
JVM polyglotte
Dois-je coder en java pour exécuter un programme
sur la JVM?
Oui, mais pas que, fais-toi plaisir!
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”
Polyglotte
var 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
Polyglotte
server = 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
Polyglotte
def 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
Polyglotte
public 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
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
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
Verticle
JsonObject 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!");
}
});
Event-bus
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
Event-bus
● Enregistrer un handler
● Dé-référencer un handler
● Adresses
● Messages
○ Publish / subscribe
○ Point à point
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!");
});
Event-bus
Enregistrer un handler
MessageConsumer<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!");
}
});
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ête
DeliveryOptions options = new DeliveryOptions();
options.addHeader("some-header", "some-value");
eventBus.send("news.uk.sport", "You kicked a ball",
options);
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"
});
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 resources
mainRouter.route("/static/*").handler(StaticHandler.create());
mainRouter.route(".*.templ").handler(myTemplateHandler);
mainRouter.mountSubRouter("/productsAPI", restAPI);
$curl http://localhost:8080/productsAPI/products/product/1234
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();
}
});
}
Benchmarks
Source : http://www.cubrid.org
Benchmarks
Source : https://www.techempower.com/benchmarks/#section=data-r8&hw=i7&test=plaintext
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
Production ready
Bonus
Si vous aimez vraiment Tomcat :
Exposer une API REST : http://sparkjava.com
import static spark.Spark.*;
public class HelloWorld {
public static void main(String[] args) {
get("/hello", (req, res) -> "Hello World");
}
}
Bonus
Si vous aimez vraiment Tomcat :
Consommer une API REST : http://unirest.io
HttpResponse<JsonNode> jsonResponse =
Unirest.post("http://httpbin.org/post")
.queryString("name", "Mark")
.field("last", "Polo")
.asJson();
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

Contenu connexe

Vert.x 3

  • 1. Vert.x 3 high performance polyglot application toolkit
  • 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
  • 4. Vocabulaire pour commerciaux Simple threadSafe concurrent asynchronous eventDriven reactive eventBus over a scalable polyglot embeddable toolkit plateform
  • 5. Le problème ● Répondre à un grand nombre de clients en même temps ● C10k = 10 000 connexions simultanées
  • 10. C10k Tomcat : 200 threads = 200 connexions Les appels suivants doivent attendre
  • 11. C10k ● Scalable verticalement et horizontalement ● Distribué ● Événementiel et asynchrone ● I/O non bloquantes ● Tolérant à la panne ● Extensible
  • 12. 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
  • 13. 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 ○ …
  • 14. 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
  • 15. 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
  • 16. 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
  • 17. 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
  • 18. JVM polyglotte Dois-je coder en java pour exécuter un programme sur la JVM? Oui, mais pas que, fais-toi plaisir!
  • 19. 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”
  • 20. Polyglotte var 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
  • 21. Polyglotte server = 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
  • 22. Polyglotte def 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
  • 23. Polyglotte public 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
  • 24. 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
  • 25. 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
  • 26. Verticle JsonObject 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!"); } });
  • 28. 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
  • 29. Event-bus ● Enregistrer un handler ● Dé-référencer un handler ● Adresses ● Messages ○ Publish / subscribe ○ Point à point
  • 30. 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!"); });
  • 31. Event-bus Enregistrer un handler MessageConsumer<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!"); } });
  • 32. 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ête DeliveryOptions options = new DeliveryOptions(); options.addHeader("some-header", "some-value"); eventBus.send("news.uk.sport", "You kicked a ball", options);
  • 33. 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" });
  • 34. 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 resources mainRouter.route("/static/*").handler(StaticHandler.create()); mainRouter.route(".*.templ").handler(myTemplateHandler); mainRouter.mountSubRouter("/productsAPI", restAPI); $curl http://localhost:8080/productsAPI/products/product/1234
  • 35. 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(); } }); }
  • 38. 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
  • 40. Bonus Si vous aimez vraiment Tomcat : Exposer une API REST : http://sparkjava.com import static spark.Spark.*; public class HelloWorld { public static void main(String[] args) { get("/hello", (req, res) -> "Hello World"); } }
  • 41. Bonus Si vous aimez vraiment Tomcat : Consommer une API REST : http://unirest.io HttpResponse<JsonNode> jsonResponse = Unirest.post("http://httpbin.org/post") .queryString("name", "Mark") .field("last", "Polo") .asJson();
  • 42. 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