Migration de Tomcat vers Vert.x

5,720 views

Published on

Présentation données pendant Devoxx France 2015 : migration de Tomcat vers Vert.x

Published in: Technology
  • Be the first to comment

Migration de Tomcat vers Vert.x

  1. 1. @FlorianBoulay#devoxxFr Migration d'une webapp Tomcat vers Vert.x (ou Servlet contre Vert.x)
  2. 2. Moi Florian Boulay Développeur chez NextPerf @FlorianBoulay Motivations pour ce talk : Partager un retour sur un sujet non documenté
  3. 3. @FlorianBoulay#devoxxFr Plan 1 - Présentation Vert.x 2 - Migration de Tomcat vers Vert.x Q & A pendant tout le talk !
  4. 4. @YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr Rappels sur Vert.x
  5. 5. @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.
  6. 6. @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
  7. 7. @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
  8. 8. @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); } }
  9. 9. @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.
  10. 10. @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)
  11. 11. @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);
  12. 12. @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
  13. 13. @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)
  14. 14. @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
  15. 15. @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 !!
  16. 16. @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);
  17. 17. Servlet vs Vert.x
  18. 18. @FlorianBoulay#devoxxFr Points abordés ➢ Moteur de template ➢ HttpServletRequest HttpServerRequest→ ➢ Class loaders ➢ Librairies incompatibles ➢ Librairies avec IO bloquantes ➢ Déploiement ➢ Sessions
  19. 19. @YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr Moteur de template
  20. 20. @FlorianBoulay#devoxxFr Moteur de template -Tomcat (1) Moteurs de template compatibles Servlet ainsi que ceux des spécifications JSP, JSF
  21. 21. @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");
  22. 22. @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
  23. 23. @FlorianBoulay#devoxxFr Moteur de template – Vert.x (3) Pas facile
  24. 24. @YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr HttpServletRequest → HttpServerRequest
  25. 25. @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
  26. 26. @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
  27. 27. @FlorianBoulay#devoxxFr HttpServ(l)e(t|r)Request (3) Facile Tant que ce qui est envoyé n'est pas du fichier HTML dynamique
  28. 28. @YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr Class loaders
  29. 29. @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
  30. 30. @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)
  31. 31. @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
  32. 32. @FlorianBoulay#devoxxFr Class loaders Pas facile
  33. 33. @YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr Librairies avec IO bloquantes
  34. 34. @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
  35. 35. @FlorianBoulay#devoxxFr Librairies avec IO bloquantes Facile
  36. 36. @YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr Déploiement
  37. 37. @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
  38. 38. @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
  39. 39. @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
  40. 40. @FlorianBoulay#devoxxFr Déploiement Facile
  41. 41. @YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr Sessions
  42. 42. @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.
  43. 43. @FlorianBoulay#devoxxFr Sessions neutre
  44. 44. @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
  45. 45. @FlorianBoulay#devoxxFr Références Concepts : http://vertx.io/manual.html
  46. 46. @YourTwitterHandle@YourTwitterHandle @FlorianBoulay#devoxxFr Q & A

×