@FlorianBoulay#devoxxFr
Migration d'une webapp Tomcat
vers Vert.x
(ou Servlet contre Vert.x)
Moi
Florian Boulay
Développeur chez NextPerf
@FlorianBoulay
Motivations pour ce talk : Partager un retour sur un sujet non documenté
@FlorianBoulay#devoxxFr
Plan
1 - Présentation Vert.x
2 - Migration de Tomcat vers Vert.x
Q & A pendant tout le talk !
@YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr
Rappels sur Vert.x
@FlorianBoulay#devoxxFr
Résumé de Vert.x
Vert.x est une plate-forme très légère, très
performante tournant sur la JVM.
@FlorianBoulay#devoxxFr
Résumé de Vert.x
Quelques caractéristiques :
➔
Polyglote : tous langages tournant sur la JVM
➔
Scalable : API utilisant des IO non bloquantes et
asynchrone.
➔
Évenementielle
➔
Rapide, très léger
➔
Construit au dessus de Netty
Ce talk est sur la version 2.1
@FlorianBoulay#devoxxFr
Résumé de Vert.x
Ce qu'on peut construire avec Vert.x :
✔
API REST
✔
Webapp
✔
Applications server
✔
Frameworks de plus haut niveau
@FlorianBoulay#devoxxFr
Création d'un serveur HTTP
public class Server extends Verticle {
public void start() {
vertx.createHttpServer().requestHandler(new Handler<HttpServerRequest>() {
public void handle(HttpServerRequest req) {
req.response()
.putHeader("content-type", "text/html")
.end("<html><body><h1>Hello from vert.x!</h1></body></html>");
}
}).listen(8080);
}
}
@FlorianBoulay#devoxxFr
Création d'un serveur HTTP
Java 8
public class Server extends Verticle {
public void start() {
vertx.createHttpServer().requestHandler(req -> {
req.response()
.putHeader("content-type", "text/html")
.end("<html><body><h1>Hello from vert.x!</h1></body></html>");
}).listen(8080);
}
}
Code asynchrone basé sur des callback. Modèle
inspiré de Node.js. Callback hell possible.
@FlorianBoulay#devoxxFr
Création d'un serveur HTTP
Javascript
var vertx = require('vertx');
vertx.createHttpServer().requestHandler(function(req) {
request.response.putHeader("content-type", "text/html")
req.response.end("<html><body><h1>Hello from vert.x!
</h1></body></html>");
}).listen(8080)
var vertx = require('vertx');
vertx.createHttpServer().requestHandler(function(req) {
var file = req.path() === '/' ? 'index.html' : req.path();
req.response.sendFile('webroot/' + file);
}).listen(8080)
@FlorianBoulay#devoxxFr
Création d'un serveur HTTP
Node.js
var http = require("http");
var server = http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/html"});
response.write("<html><body><h1>Hello from vert.x!</h1></body></html>");
response.end();
});
server.listen(8080);
var vertx = require('vertx');
vertx.createHttpServer().requestHandler(function(req) {
var file = req.path() === '/' ? 'index.html' : req.path();
req.response.sendFile('webroot/' + file);
}).listen(8080)
var http = require("http");var server = http.createServer(function(request, response) { response.writeHead(200, {"Content-Type": "text/html"}); response.write("<!DOCTYPE "html">"); response.write("<html>"); response.write("<head>"); response.write("<title>Hello World Page</title>"); response.write("</head>"); response.write("<body>"); response.write("Hello
World!"); response.write("</body>"); response.write("</html>"); response.end();}); server.listen(80);
@FlorianBoulay#devoxxFr
Verticle – intro
✔
Point d'entrée de l'application
✔
Plusieurs verticles sont possibles
✔
Packaging d'un ou plusieurs verticle en
module
✔
Les modules sont les « libs » de Vert.x
@FlorianBoulay#devoxxFr
Verticle – Thread model (1)
➢
Chaque verticle est exécuté par un unique
thread à un instant donné
➢
Programmation d'un verticle comme une
application mono threadé
Règle d'or : ne pas bloquer l'event loop
(thread exécutant un verticle)
@FlorianBoulay#devoxxFr
Verticle – Thread model (2)
➢
Pour appeler des librairies bloquantes, il faut
les faire s'exécuter dans un worker verticle
➢
Rend compatible toutes les librairies existantes
bloquantes
@FlorianBoulay#devoxxFr
Verticle – communication (1)
✔
Communications via l'event bus entre Verticle
de la même JVM ou entre JVM
✔
Différents types supportés : pour être
compatible tout langage, JSON est un bon
format
✔
Modèle proche des acteurs
✔
Communication possible vers le browser !!
@FlorianBoulay#devoxxFr
Verticle – communication (2)
// send a message
EventBus eb = vertx.eventBus();
eb.send("verticle.address", "hello world");
// receive a message
Handler<Message<String>> myHandler = message -> {
System.out.println("I received a message " + message.body());
message.reply("This is a reply");
};
eb.registerHandler("verticle.address", myHandler);
Servlet
vs
Vert.x
@FlorianBoulay#devoxxFr
Points abordés
➢
Moteur de template
➢
HttpServletRequest HttpServerRequest→
➢
Class loaders
➢
Librairies incompatibles
➢
Librairies avec IO bloquantes
➢
Déploiement
➢
Sessions
@YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr
Moteur de template
@FlorianBoulay#devoxxFr
Moteur de template -Tomcat (1)
Moteurs de template compatibles Servlet ainsi
que ceux des spécifications JSP, JSF
@FlorianBoulay#devoxxFr
Moteur de template – Vert.x (2)
✔
Vert.x est uniquement un client et un serveur
HTTP
✔
API de bas niveau permettant d'écrire du code
dans une réponse HTTP ou d'envoyer un fichier
statique HTML
// HTML envoyé dans la réponse
req.response()
.putHeader("content-type", "text/html")
.end("<html><body><h1>Hello from vert.x!</h1></body></html>");
// Envoi d'un fichier statique
req.response().sendFile("webroot/index.html");
@FlorianBoulay#devoxxFr
Moteur de template – Vert.x (3)
➔
Intégration d'un moteur de template possible
➔
Il faut lire la doc
➔
Plus ou moins difficile selon le moteur
@FlorianBoulay#devoxxFr
Moteur de template – Vert.x (3)
Pas facile
@YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr
HttpServletRequest
→
HttpServerRequest
@FlorianBoulay#devoxxFr
HttpServ(l)e(t|r)Request (1)
// Vert.x
req.response()
.setStatusCode(200)
.putHeader("content-type", "text/html")
.end("<html><body><h1>Hello from vert.x!</h1></body></html>");
// Servlet
response.setStatus(200);
response.setHeader("content-type", "text/html");
PrintWriter out = response.getWriter();
out.write("<html><body><h1>Hello from vert.x!</h1></body></html>");
out.close();
API Proche
@FlorianBoulay#devoxxFr
HttpServ(l)e(t|r)Request (2)
// Servlet
String param = request.getParameter("debug");
// Vert.x
String param = req.params().get("debug");
API Proche
@FlorianBoulay#devoxxFr
HttpServ(l)e(t|r)Request (3)
Facile
Tant que ce qui est envoyé n'est pas du fichier HTML dynamique
@YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr
Class loaders
@FlorianBoulay#devoxxFr
Class loaders – Tomcat (1)
➢
Les webapp dans Tomcat ont un unique class
loader
➢
Toutes les classes, et tous les champs statiques
sont utilisables à tout moment
➢
Simple, mais problèmes liés aux threads
possibles
@FlorianBoulay#devoxxFr
Class loaders – Vert.x (2)
➢
Vert.x crée un class loader par instance de
Verticle
➢
Impossible d'avoir des données calculées ou
cachées statiques (ex: LoadingCache Guava)
@FlorianBoulay#devoxxFr
Class loaders – Vert.x (3)
Alternatives :
✔
shared data : maps et sets globaux contenant
des data immutables
✔
Cache externe type Memcache, Redis
✔
Interroger un Verticle faisant office de cache
@FlorianBoulay#devoxxFr
Class loaders
Pas facile
@YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr
Librairies avec IO
bloquantes
@FlorianBoulay#devoxxFr
Librairies avec IO bloquantes
➢
Les librairies avec IO bloquantes (JDBC,
Lecture de fichier…) doivent être isolées dans
des worker Verticle
➢
Certaines peuvent être remplacées, ex : JDBC
par le module Mysql Postgresql asynchrone
@FlorianBoulay#devoxxFr
Librairies avec IO bloquantes
Facile
@YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr
Déploiement
@FlorianBoulay#devoxxFr
Déploiement – Tomcat (1)
➔
Peu de typologies possibles avec Tomcat : 1
war (ou webapp explosée) sur un serveur ayant
Tomcat installé
➔
Plus scalable avec une webapp stateless
➔
Application avec état difficilement scalable
@FlorianBoulay#devoxxFr
Déploiement – Vert.x (2)
Possibilités au niveau le plus fin, le Verticle :
✔
Une application autonome avec tous les
Verticle en mode stateless sur chaque serveur.
✔
Chaque Verticle dans sa JVM. Communiquant
ensemble via l'event bus
✔
Un mix des 2, avec High Availibility
@FlorianBoulay#devoxxFr
Déploiement – Vert.x (3)
Possibilité au niveau applicatif :
✔
Une application peut être lancée en ligne de
commande avec la commande vertx
✔
Une application peut être packagé et être
lancée avec un java -jar
✔
Déploiement à partir du code
Facile
@FlorianBoulay#devoxxFr
Déploiement
Facile
@YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr
Sessions
@FlorianBoulay#devoxxFr
Sessions
➢
Si votre appli est stateful il faudra externaliser
l'état, via un cache par exemple
➢
Si l'appli est stateless, il ne devrait pas y avoir
de problème
➢
Si il y a de l'authentification via cookie, il
faudra la recoder.
@FlorianBoulay#devoxxFr
Sessions
neutre
@YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr
Summary
➔ Si c'est une webapp : difficile en cas de moteur non
transposable
➔ Si il s'agit d'un serveur de services REST : envisagée
➔ Si c'est une application server to server : difficile si beaucoup
de champs statiques
@FlorianBoulay#devoxxFr
Références
Concepts : http://vertx.io/manual.html
@YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr
Q & A

Migration de Tomcat vers Vert.x