46
@FlorianBoulay #devoxxFr Migration d'une webapp Tomcat vers Vert.x (ou Servlet contre Vert.x)

Migration de Tomcat vers Vert.x

Embed Size (px)

Citation preview

@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.xQuelques 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.xCe qu'on peut construire avec Vert.x :

✔ API REST✔ Webapp✔ Applications server✔ Frameworks de plus haut niveau

@FlorianBoulay#devoxxFr

Création d'un serveur HTTPpublic 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 8public 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

Javascriptvar 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.jsvar 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 messageEventBus eb = vertx.eventBus();eb.send("verticle.address", "hello world");

// receive a messageHandler<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éponsereq.response() .putHeader("content-type", "text/html") .end("<html><body><h1>Hello from vert.x!</h1></body></html>");

// Envoi d'un fichier statiquereq.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.xreq.response() .setStatusCode(200) .putHeader("content-type", "text/html") .end("<html><body><h1>Hello from vert.x!</h1></body></html>");

// Servletresponse.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)

// ServletString param = request.getParameter("debug");

// Vert.xString param = req.params().get("debug");

API Proche

@FlorianBoulay#devoxxFr

HttpServ(l)e(t|r)Request (3)

FacileTant 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