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
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
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();
}
});
}
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