Run java vs ruby

1,560 views
1,439 views

Published on

0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,560
On SlideShare
0
From Embeds
0
Number of Embeds
38
Actions
Shares
0
Downloads
18
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Run java vs ruby

  1. 1. Retour d’expérience Applications webRun Java vs Run Ruby bpa@octo.com
  2. 2. De quoi on parle ? Une application webClients Serveur Application web Base de données
  3. 3. Sommaire• Les langages• Les application web• Le déploiement• La gestion des dépendances• Scalabilité
  4. 4. LES LANGAGES
  5. 5. • Langage « mainstream » • Langage non• Compilé « mainstream »• Statiquement typé • Interprété • Dynamiquement typé
  6. 6. Avantages• La JVM : un bijou très optimisé• Beaucoup de recul• Gros parc déployé• Beaucoup de compétences sur le marché• Nouveaux langages qui arrivent
  7. 7. Virtual Machine Java• Oracle : Hotspot – Open JDK• IBM – Utilisée avec Websphere• BEA : jRockitPrincipales différences au niveau du GCConvergence sur Hotspot et OpenJDK
  8. 8. Avantages• Langage hyper expressif• Adapté au scripting• Plus simple (notamment réutilisation)• Plus « 2011 » – gem install heroku – rvm
  9. 9. Exemplesdef chrono msg start = Time.now.to_i yield puts "#{msg} : #{Time.now.to_i - start} sec"endchrono "Long operation" do run_very_long_operationendclass Integer def hex to_s(16) endend12.Hex => "c"[1, 4, 10].map{|x| 2 * x}.sort => [2, 8, 20]
  10. 10. Virtual Machine Ruby• Mat’z Ruby Interpreter (MRI) – Version 1.8 • Implémentation originale – Version 1.9 • « Vraie » VM : JIT, GC• Ruby Entreprise Edition – Fork de MRI 1.8 – Copy on write, GC optimisé• jRuby – Bénéficie des performances de la JVM – De loin la plus performante VM pour Ruby (1.8 et 1.9) En production : Un peut de tout …
  11. 11. APPLICATION WEB
  12. 12. Application Web Java code source compilation.java .class déploiement .war .jar.jsp .css .jpg
  13. 13. Stack Java « light »war1 war2 Application 1 Application 2 Framework web 1 Framework web 2 Spring MVC … javax.servlet API Stack HTTP Java Tomcat, Jetty Frontal HTTP Apache2, Nginx
  14. 14. Stack Java standardwar1 Application 1 Framework web 1 Queue javax.servlet Annuaire Jboss, Weblogic, Websphere Stack HTTP Java EJB Container Serveur d’application Frontal HTTP Apache2, Nginx
  15. 15. requête HTTP Parallélisme Frontal HTTP JVMStack HTTP Java Thread worker 1 javax.servlet choix d’unthread worker Application Thread worker 2 Thread worker 3 Thread worker 4Mémoire partagée entre les threads => session stockée en mémoire
  16. 16. Stack Java NG• Nouvelles stacks qui apparaissent – Netty : asynchronisme – Play! : plus de javax.servlet
  17. 17. Serveur d’applications Java• Coût – Weblogic, Websphere : $$$$$$$$$$$$$$$$$ – Jboss : $$$ (support)• Dépendance des applications vis à vis du serveur d’application qui offre beaucoup de services• Lourd – Développement – Déploiement – Run• En as-t-on vraiment besoin ? – Même Gartner a dit non
  18. 18. Url• www.octo.com/myAppPlusieurs applications sur le même domaineAttention au référencement, aux url, aux cookiesDifficile de faire myApp.octo.com
  19. 19. Application Web Rubycode source .rb déploiement .erb .css .jpg
  20. 20. Stack ruby Application Framework web Rails, SinatraRack (API + Implémentation)Serveur d’application Ruby Unicorn, Passenger, Thin Frontal HTTP Apache2, Nginx
  21. 21. requête HTTP Unicorn Frontal HTTP Process UNIX unicorn (C + Ruby)Master Unicorn Worker Unicorn 1 Rack Application socket unix Worker Unicorn 2 Rack Application Worker Unicorn 3 Rack Application  Rôle du master : Démarrer et surveiller les workers  Pas de mémoire partageé entre les workers  Le load balancing entre les workers est assuré par la socket Unix
  22. 22. Mongrelrequête HTTP port 1901 Mongrel 1 Rack ApplicationFrontal HTTP port 1902 Mongrel 2 Rack Application port 1903 Mongrel 3 Rack Application  1 port TCP, 1 processus unix par worker  Le frontal http assure le load balancing  Pas de mémoire partagée entre les workers
  23. 23. Passenger requête HTTP Apache 2 Nginx Worker 1 Rack ApplicationModule Passenger Worker 2 Rack Application Worker 3 Rack Application Passenger est intégré au frontal HTTP en tant que module Les workers sont des processus Unix Gestion dynamique des workers par Passenger (en fonction de la charge) Pas de mémoire partagé entre les workers
  24. 24. Sessions HTTP• Rails : Plusieurs types de session store – Cookies (défaut) – FileSystem – Memcache – DB –…
  25. 25. PHP requête HTTPApache 2 Prefork Apache 2 worker 1 PHP Application Apache 2 worker 2 PHP Application Apache 2 worker 3 PHP Application  Pas de mémoire partagé entre les workers  Sessions stockés sur le disque
  26. 26. Serveur d’applications Ruby• Rôle : – Implémenter la couche HTTP <> Rack • Est capable de lancer une application Rack – Gérer le parallélisme• Points différenciant entre les implémentations – Stratégies de gestion du parallélisme – Facilitée d’installation / déploiement / configuration – Gestion des redéploiements• Points communs – Pas de mémoire partagées entre les workers – Inefficace pour servir le contenu statique
  27. 27. Multi thread en Ruby• Existe mais est peu utilisé• 1.8 – Implémentation à ne pas utiliser• 1.9 – Meilleure implémentation – Toujours pas dans la culture RubyA tester : Run d’une application Rails en jRuby
  28. 28. jRuby• Lenteur des commandes – rails, rake – Dues à l’instanciation de la JVM• Pour faire un war – Quelques adaptations dans le Gemfile – warble • Le war contient les gems• Déploiement sous tomcat ok – Quelques problèmes liés à Rails – Pas d’impression de vitesse
  29. 29. Url• myApp.octo.comUne application par domaineSSL compliqué à mettre en placeDifficile de faire www.octo.com/myApp
  30. 30. delayed_jobs Créer un job Récupère le job Worker 1 Application web Base de Stocke le données Worker 2 résultat Récupère le résultat Application et workers : même code, même application Workers lancés séparéments Exemple • Envoyer un mail • Interaction avec un service de paiement
  31. 31. Batchs Web• Les serveurs • Les delayed_jobs sont d’applications souvent utilisés au implémentent JMS cœur des applications – Rarement utilisé dans les Web applications Web – Pas forcément facile à déployer en production – Très efficace pour les performances
  32. 32. Serveur d’applications• Stack standard • Petit – Enorme (et souvent cher) – Pas chez nos clients …• Stack lights ou NG – Pas chez nos clients …• Plusieurs Webapp • 1 seul Webapp• Parallélisme par threads • Différentes stratégies de parallélisme• Mémoire partagées entre • Pas de mémoire partagée les threads
  33. 33. Application Web • Stack web relativement proche• Stack « veillissante » en • Stack ruby un peu évolution moins lourde
  34. 34. GESTION DES DÉPENDANCES
  35. 35. Dépendances Java• Outil : Maven <groupId>fr.octo.apogee</groupId> <artifactId>core</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>org.hibernate</groupId> <artifactId>core</artifactId> <version>3.2</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies>
  36. 36. Dépendances Java JVM Serveur d’applicationApplication (war)WEB-INF/classes WEB-INF/lib lib du serveur d’application lib JDK
  37. 37. Bibliothèques spécifiques Création Utilisation Déclare l’utilisation de Développeur Code la bibliothèque Développeur la bibliothèque Gestion de configuration Maven récupère la Bibiothèque dans Nexus Intégration Construit l’artefact continueStocke l’artefact Nexus Dépôt d’entreprise Proxy internet
  38. 38. Dépendances Ruby• Outil : bundler & gem Gemfile• Gem – Repo local de gem gem rails, 3.1.0 – gem install rails gem json gem sass-rails’ gem fastercsv• Bundler gem typus, 3.1.0.rc17 – Liste les dépendances gem foreigner’ – Installe les dépendances gem cancan manquantes group :development do • bundle gem sqlite3 gem capistrano end
  39. 39. Gems• Utilisation courante de librairies en C – Exemple 1 : libxml pour nokogiri – Exemple 2 : libmysql pour mysql• Conséquences – Besoin d’avoir gcc, make, automake … – Besoin d’avoir les headers • aptitude install libmysql-dev Pas très pratique pour le déploiement en production
  40. 40. Dépendances RubyServeur d’application Gem Repository Gem A v 1.1 Application Gem B v 0.7 *.rb Gem C v 1.9 *.rb …
  41. 41. Bibliothèques spécifiques Création Utilisation Déclare l’utilisation deDéveloppeur Code la bibliothèque Développeur la bibliothèque Bundler récupère la bibliothèque dans le gestionnaire de configuration Gestion de configuration
  42. 42. Gestion des dépendances • Système de description des dépendances • Système de récupération des dépendances sur Internet• Outil : Maven • Outil : Gem + Bundler• Toutes les dépendances sont dans • Les dépendances sont dans le le war repo local de gems• Conflit de classes (App / Serveur • Peu de conflits d’app / JDK) • Dépendances sur gcc et les headers de développements• Dépots d’entreprises • Pas de dépôts d’entreprises – Nexus
  43. 43. DÉPLOIEMENT
  44. 44. DéploiementTomcat, Jetty, Jboss dépôt dans un dossier .warJboss, Websphere appel d’une API sur le serveur d’application .war • Peut déployer sur un cluster • Est en général long
  45. 45. Pré requis serveur• Un OS• Un JDK (packagé avec l’OS)• Un serveur d’application• Eventuellement un serveur webRelativement simple
  46. 46. Déploiementcode source .rb dépôt dans un dossier .erb Installation des gems .css .jpg nécessaires signaler au serveur d’application la nouvelle version
  47. 47. Déploiement avec Capistrano Serveur Gestion de d’application configuration checkout current symlink cap deployapp_directory shared 201112061223 1. Checkout du code 2. Préparation du code releases 201112061421 3. Symlink 4. Signal au serveur 201112061526 d’application cap rollback
  48. 48. Capistrano• Outil écrit en Ruby – Moteur de scripting qui exécute du shell – Apporte une structure de déploiement propre à partir du gestionnaire de configuration• Gère le multi machine (via SSH) – Déployer sur 15 machines = déployer sur une• Gère les différents types de machines – Configurer la base de données, memcache
  49. 49. Exemple Skillstarcap deploy – Passe la plateforme en maintenance – Déploie l’appli sinatra sur les query server – Execute les scripts de migration de base de données – Purge les caches – Mets à jour le CDN – Déploie l’appli rails sur les frontaux – Sort l’application de maintenance
  50. 50. Pré requis serveur• Un OS• Ruby (packagé dans l’OS)• Git• Build-essentials (gcc, make …)• Des librairies en dev• RVM, pour installer un autre ruby• Un serveur web• Bundler (installé en gem) Peut rapidement devenir complexeExemple :• rvm-shell default -c ‘RAILS_ENV=production bundle exec rake db:migrate’• Installation de passenger qui recompile un module Nginx
  51. 51. Hot deploy• Déploiement « Hot deploy » – 0 down time – On ne perds aucune requête client – Le client ne s’aperçoit de rienPossible quand on ne touche pas au schéma de la baseNécessaire pour le « continuous delivery »
  52. 52. Hot deploy• Incompatible avec la notion de War• Solution : 2 serveurs, et on bascule Load balancer Frontal HTTP Frontal HTTP Serveur d’app Serveur d’app
  53. 53. Hot deploy• Natif – Passenger : touch tmp/restart.txt – Unicorn : kill –s USR2 pid• Nginx – Mise à jour des binaires à chaudFonctionnalité implicite dans l’écosystème ruby
  54. 54. Hot deploy Unicorn$ pgrep -lf unicorn_rails12113 unicorn_rails master -c config/unicorn.rb -D12118 unicorn_rails worker[0] -c config/unicorn.rb -D12136 unicorn_rails worker[1] -c config/unicorn.rb -D12137 unicorn_rails worker[2] -c config/unicorn.rb -D$ kill -s USR2 12113$ pgrep -lf unicorn_rails12113 unicorn_rails master (old) -c config/unicorn.rb -D12118 unicorn_rails worker[0] -c config/unicorn.rb -D12136 unicorn_rails worker[1] -c config/unicorn.rb -D12137 unicorn_rails worker[2] -c config/unicorn.rb -D12239 /usr/bin/ruby1.8 /usr/bin/unicorn_rails -c config/unicorn.rb -D$ pgrep -lf unicorn_rails12239 unicorn_rails master -c config/unicorn.rb -D12245 unicorn_rails worker[0] -c config/unicorn.rb -D12246 unicorn_rails worker[1] -c config/unicorn.rb -D
  55. 55. Configuration Base de données• Soit dans un .properties • Un fichier yml dans dans le war « shared »• Soit par une Datasource • Un symlink Peut être complexe  Simple et efficace
  56. 56. Logs• Gérer par le serveur • Symlink vers un d’application répertoire dans• Configuration en « shared » général embarquée • Mélange potentiel entre dans le war workers Sujet maîtrisé  Sujet qui peut devenir complexe
  57. 57. Déploiement• Déploiement simple sur • Simple sur le papier, les stacks simple mais socle compliqué à• Se complexifie avec la initialiser complexité des serveur • heroku.com, d’applications engineyard.com• Pas de hot deploy • Hot deploy natif• Déploiement multi • Déploiement multi machine plus complexe machine simple
  58. 58. SCALABILITÉ
  59. 59. Scalabilité mono machine • ~ 50 threads par serveurs d’application Frontal HTTP – En général ~20 de workers – Difficile de monter bien plus haut Serveur d’app • Le serveur d’application sert souvent le statique • Mémoire en communThread 1 Thread 2 Thread 3 – Cache, notamment L2 • Un serveur d’application = 1 processus Unix – L’utilisation de toutes les ressources CPU et Shared memory RAM sur une grosse machine peut être difficileBase de données
  60. 60. Scalabilité mono machine • Le serveur d’application ne sert pas le Frontal HTTP contenu statique • Pas de mémoire partagé, mais « copy Serveur d’app on write » entre les workers • Pas d’utilisation de threads, la scalabilité repose sur l’augmentation du nombre de Session Store workersWorker 1 Worker 2 Worker 3 • Application de fait stateless • Architecture nativement plus « distribuée » • Mesures de performances plus facile à faire car pas de JVM qui masque tout Base de données
  61. 61. Scalabilité multi machine Load balancerFrontal HTTP Frontal HTTP Frontal HTTPServeur d’app Serveur d’app Serveur d’app Base de • Mise en place d’affinité de session données • Mise en place de caches partagés
  62. 62. Scalabilité multi machine Load balancerFrontal HTTP Frontal HTTP Frontal HTTPServeur d’app Serveur d’app Serveur d’app • Ne change pas grand chose par Base de rapport à mono machine  Memcache • Fail over sur la partie données application facile
  63. 63. Scalabilité• 1 seul processus (la JVM) • Utilisation des ressources doit utiliser toutes les par plusieurs processus ressources• Cache communs à tous • Pas de caches communs les workers natifs• Langage rapide • Langage « suffisamment » rapide• La scalabilité est à • Le besoin de scalabilité implémenter au dessus horizontal est pris en de la stack compte dans la stack – Souvent par un serveur d’application gérant le clustering
  64. 64. Optimisation• Stack complexe, donc • Stack plus simple complexe à optimiser – JVM  Les gains en – Serveur d’application performances sont – Frameworks recherchés sur – Application l’application Gain en performances significatif en optimisant la stack sous l’application
  65. 65. SUPERVISION / OUTILLAGE
  66. 66. Supervision Outillage• Visual VM• JMX• Profiling• Debugging à distance• Memory analyzer• …
  67. 67. Supervision Outillage• cat, tail, ps, curl …Pas grand chose (ou compliqué)Mais ce n’est pas forcément une douleur – Plus simple – On utilise les outils jusqu’au bout
  68. 68. Outils Ruby• Tendance observée :De plus en plus d’outils Infra en Ruby• capistrano• god• puppet• chefRuby est de plus en plus utilisé en infra pure
  69. 69. CONCLUSION
  70. 70. Conclusion• Le run Ruby – Est « Production Ready » • mais pas super industrialisé • moins performant que Java – Force une architecture prête à scaler dès le début• Le run Java – Repose sur la JVM qui reste un bijou technologique sans équivalent – Est en train de muter pour sortir des « usines à gaz »• Culture différente – Java : application de gestion – Ruby : Web

×