70
Retour d’expérience Applications web Run Java vs Run Ruby [email protected]

Run java vs ruby

Embed Size (px)

Citation preview

Page 1: Run java vs ruby

Retour d’expérienceApplications web

Run Java vs Run Ruby

[email protected]

Page 2: Run java vs ruby

De quoi on parle ?Une application web

Serveur

Base de données

Application web

Clients

Page 3: Run java vs ruby

Sommaire

• Les langages• Les application web• Le déploiement• La gestion des dépendances• Scalabilité

Page 4: Run java vs ruby

LES LANGAGES

Page 5: Run java vs ruby

• Langage « mainstream »• Compilé• Statiquement typé

• Langage non « mainstream »

• Interprété• Dynamiquement typé

Page 6: Run java vs ruby

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

Page 7: Run java vs ruby

Virtual MachineJava

• Oracle : Hotspot– Open JDK

• IBM– Utilisée avec Websphere

• BEA : jRockit

Principales différences au niveau du GCConvergence sur Hotspot et OpenJDK

Page 8: Run java vs ruby

Avantages

• Langage hyper expressif• Adapté au scripting• Plus simple (notamment réutilisation)• Plus « 2011 »– gem install heroku– rvm

Page 9: Run java vs ruby

Exemplesdef chrono msg start = Time.now.to_i yield puts "#{msg} : #{Time.now.to_i - start} sec"end

chrono "Long operation" do run_very_long_operationend

class Integer def hex to_s(16) endend12.Hex => "c"

[1, 4, 10].map{|x| 2 * x}.sort => [2, 8, 20]

Redéfinition des

classes de bases

Passages de fonctions

en paramètres

Expressivité

Page 10: Run java vs ruby

Virtual MachineRuby

• 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 …

Page 11: Run java vs ruby

APPLICATION WEB

Page 12: Run java vs ruby

Application WebJava

.java

.jsp

.css

.jpg

.jar

.class

.war

compilation

déploiement

code source

Page 13: Run java vs ruby

Stack Java« light »

javax.servlet

Stack HTTP Java

Frontal HTTP

Framework web 2

Application 2

Apache2, Nginx

Spring MVC …

Tomcat, Jetty

Framework web 1

Application 1

war2war1

API

Page 14: Run java vs ruby

Stack Javastandard

Frontal HTTP Apache2, Nginx

Serveur d’application

Jboss, Weblogic, Websphere

javax.servlet

Stack HTTP Java

Framework web 1

Application 1

war1

EJB Container

Annuaire

Queue

Page 15: Run java vs ruby

Parallélisme

javax.servlet

Stack HTTP Java

Thread worker 1

Thread worker 2

Thread worker 3

choix d’unthread worker

Thread worker 4

Appl

icati

on

JVM

Mémoire partagée entre les threads => session stockée en mémoire

Frontal HTTP

requête HTTP

Page 16: Run java vs ruby

Stack Java NG

• Nouvelles stacks qui apparaissent– Netty : asynchronisme– Play! : plus de javax.servlet

Page 17: Run java vs ruby

Serveur d’applicationsJava

• Coût– Weblogic, Websphere : $$$$$$$$$$$$$$$$$– Jboss : $$$ (support)

• Dépendance des applications vis à visdu serveur d’application qui offre beaucoupde services

• Lourd– Développement– Déploiement – Run

• En as-t-on vraiment besoin ?– Même Gartner a dit non

Page 18: Run java vs ruby

Url

• www.octo.com/myApp

Plusieurs applications sur le même domaineAttention au référencement, aux url, aux

cookies

Difficile de faire myApp.octo.com

Page 19: Run java vs ruby

Application WebRuby

.rb

.erb

.css

.jpg

déploiement

code source

Page 20: Run java vs ruby

Stack ruby

Serveur d’application Ruby

Frontal HTTP Apache2, Nginx

Unicorn, Passenger, Thin

Rack (API + Implémentation)

Framework web Rails, Sinatra

Application

Page 21: Run java vs ruby

Frontal HTTP

Unicorn

Master Unicorn

Worker Unicorn 1

socketunix

Application

requête HTTP

Rack

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

Process UNIX unicorn (C + Ruby)

Worker Unicorn 2 ApplicationRack

Worker Unicorn 3 ApplicationRack

Page 22: Run java vs ruby

Frontal HTTP

Mongrel

Mongrel 1 Applicationrequête HTTP

Rack

Mongrel 2 ApplicationRack

Mongrel 3 ApplicationRack

1 port TCP, 1 processus unix par worker Le frontal http assure le load balancing Pas de mémoire partagée entre les workers

port 1901

port 1902

port 1903

Page 23: Run java vs ruby

Apache 2Nginx

Module Passenger

Passenger

Worker 1 Application

requête HTTP

Rack

Worker 2 ApplicationRack

Worker 3 ApplicationRack

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

Page 24: Run java vs ruby

Sessions HTTP

• Rails : Plusieurs types de session store– Cookies (défaut)– FileSystem– Memcache– DB– …

Page 25: Run java vs ruby

Apache 2 Prefork

PHP

Apache 2 worker 1 Application

requête HTTP

PHP

Pas de mémoire partagé entre les workers Sessions stockés sur le disque

Apache 2 worker 2 ApplicationPHP

Apache 2 worker 3 ApplicationPHP

Page 26: Run java vs ruby

Serveur d’applicationsRuby

• 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

Page 27: Run java vs ruby

Multi threaden 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

Page 28: Run java vs ruby

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

Page 29: Run java vs ruby

Url

• myApp.octo.com

Une application par domaineSSL compliqué à mettre en place

Difficile de faire www.octo.com/myApp

Page 30: Run java vs ruby

delayed_jobs

Base de données

Application web

Worker 1 Créer un job

Worker 2

Récupère le job

Stocke le 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

Page 31: Run java vs ruby

• Les serveurs d’applications implémentent JMS– Rarement utilisé dans les

applications Web

• Les delayed_jobs sont souvent utilisés au cœur des applications Web– Pas forcément facile à

déployer en production– Très efficace pour les

performances

Batchs Web

Page 32: Run java vs ruby

• Stack standard– Enorme (et souvent cher)

• Stack lights ou NG– Pas chez nos clients …

• Plusieurs Webapp• Parallélisme par threads

• Mémoire partagées entre les threads

• Petit– Pas chez nos clients …

• 1 seul Webapp• Différentes stratégies de

parallélisme• Pas de mémoire partagée

Serveurd’applications

Page 33: Run java vs ruby

• Stack « veillissante » en évolution

• Stack ruby un peu moins lourde

ApplicationWeb

• Stack web relativement proche

Page 34: Run java vs ruby

GESTION DES DÉPENDANCES

Page 35: Run java vs ruby

DépendancesJava

• 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>

Page 36: Run java vs ruby

JVM

Serveur d’application

DépendancesJava

Application (war)

WEB-INF/lib

WEB-INF/classes

lib du serveur d’application

lib JDK

Page 37: Run java vs ruby

Création Utilisation

Bibliothèquesspécifiques

Développeur

Gestion de configuration

Intégrationcontinue

Nexus

Code la bibliothèque

Construit l’artefact

Stocke l’artefact

Développeur Déclare l’utilisation dela bibliothèque

Maven récupère laBibiothèque dans Nexus

Dépôt d’entrepriseProxy internet

Page 38: Run java vs ruby

Dépendances Ruby

• Outil : bundler & gem

• Gem– Repo local de gem– gem install rails

• Bundler– Liste les dépendances– Installe les dépendances

manquantes• bundle

Gemfile

gem 'rails', '3.1.0'

gem 'json'gem 'sass-rails’gem 'fastercsv'gem 'typus', '3.1.0.rc17'gem 'foreigner’gem 'cancan'

group :development do gem 'sqlite3' gem 'capistrano'end

Page 39: Run java vs ruby

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

Page 40: Run java vs ruby

Serveur d’application

Application

DépendancesRuby

*.rb

*.rb

Gem Repository

Gem A v 1.1

Gem B v 0.7

Gem C v 1.9

Page 41: Run java vs ruby

Création Utilisation

Bibliothèquesspécifiques

Développeur

Gestion de configuration

Code la bibliothèque Développeur Déclare l’utilisation dela bibliothèque

Bundler récupère labibliothèque dans legestionnaire de configuration

Page 42: Run java vs ruby

• Outil : Maven• Toutes les dépendances sont dans le

war• Conflit de classes (App / Serveur

d’app / JDK)

• Dépots d’entreprises– Nexus

• Outil : Gem + Bundler• Les dépendances sont dans le

repo local de gems• Peu de conflits• Dépendances sur gcc et les

headers de développements• Pas de dépôts d’entreprises

Gestion desdépendances

• Système de description des dépendances• Système de récupération des dépendances sur

Internet

Page 43: Run java vs ruby

DÉPLOIEMENT

Page 44: Run java vs ruby

Déploiement

.wardépôt dans un dossierTomcat, Jetty, Jboss

.warappel d’une API sur le serveur d’applicationJboss, Websphere

• Peut déployer sur un cluster• Est en général long

Page 45: Run java vs ruby

Pré requis serveur

• Un OS• Un JDK (packagé avec l’OS)• Un serveur d’application• Eventuellement un serveur web

Relativement simple

Page 46: Run java vs ruby

Déploiement

.rb

.erb

.css

.jpg

code source

dépôt dans un dossier

signaler au serveur d’application la

nouvelle version

Installation des gemsnécessaires

Page 47: Run java vs ruby

Déploiementavec Capistrano

app_directory

current

shared

releases

201112061223

201112061421

201112061526

symlink

Serveur d’application

Gestion de configuration

checkout

cap deploy1. Checkout du code2. Préparation du code3. Symlink4. Signal au serveur

d’applicationcap rollback

Page 48: Run java vs ruby

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

Page 49: Run java vs ruby

ExempleSkillstar

cap 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

Page 50: Run java vs ruby

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

Page 51: Run java vs ruby

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 »

Page 52: Run java vs ruby

Hot deploy

• Incompatible avec la notion de War• Solution : 2 serveurs, et on bascule

Frontal HTTP

Serveur d’app

Frontal HTTP

Serveur d’app

Load balancer

Page 53: Run java vs ruby

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

Page 54: Run java vs ruby

Hot deployUnicorn

$ 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

Page 55: Run java vs ruby

ConfigurationBase de données

• Soit dans un .properties dans le war

• Soit par une Datasource

Peut être complexe

• Un fichier yml dans « shared »

• Un symlink

Simple et efficace

Page 56: Run java vs ruby

Logs

• Gérer par le serveur d’application

• Configuration en général embarquée dans le war

Sujet maîtrisé

• Symlink vers un répertoire dans « shared »

• Mélange potentiel entre workers

Sujet qui peut devenir complexe

Page 57: Run java vs ruby

Déploiement

• Déploiement simple sur les stacks simple

• Se complexifie avec la complexité des serveur d’applications

• Pas de hot deploy• Déploiement multi

machine plus complexe

• Simple sur le papier, mais socle compliqué à initialiser

• heroku.com, engineyard.com

• Hot deploy natif• Déploiement multi

machine simple

Page 58: Run java vs ruby

SCALABILITÉ

Page 59: Run java vs ruby

Scalabilitémono machine

Frontal HTTP

Serveur d’app

Thre

ad 1

Thre

ad 2

Thre

ad 3

Shared memory

Base de données

• ~ 50 threads par serveurs d’application– En général ~20 de workers– Difficile de monter bien plus haut

• Le serveur d’application sert souvent le statique

• Mémoire en commun– Cache, notamment L2

• Un serveur d’application = 1 processus Unix– L’utilisation de toutes les ressources CPU et

RAM sur une grosse machine peut être difficile

Page 60: Run java vs ruby

Scalabilitémono machine

Frontal HTTP

Serveur d’app

Wor

ker 1

Wor

ker 2

Wor

ker 3

Base de données

Sess

ion

Stor

e

• Le serveur d’application ne sert pas le contenu statique

• Pas de mémoire partagé, mais « copy on write » entre les workers

• Pas d’utilisation de threads, la scalabilité repose sur l’augmentation du nombre de workers

• Application de fait stateless• Architecture nativement plus « distribuée »

• Mesures de performances plus facile à faire car pas de JVM qui masque tout

Page 61: Run java vs ruby

Scalabilitémulti machine

Frontal HTTP

Serveur d’app

Base de données

Frontal HTTP

Serveur d’app

Frontal HTTP

Serveur d’app

Load balancer

• Mise en place d’affinité de session• Mise en place de caches partagés

Page 62: Run java vs ruby

Base de données

Scalabilitémulti machine

Frontal HTTP

Serveur d’app

Frontal HTTP

Serveur d’app

Frontal HTTP

Serveur d’app

Load balancer

• Ne change pas grand chose par rapport à mono machine

• Fail over sur la partie application facile

Memcache

Page 63: Run java vs ruby

Scalabilité

• 1 seul processus (la JVM) doit utiliser toutes les ressources

• Cache communs à tous les workers

• Langage rapide

• La scalabilité est à implémenter au dessus de la stack– Souvent par un serveur

d’application gérant le clustering

• Utilisation des ressources par plusieurs processus

• Pas de caches communs natifs

• Langage « suffisamment » rapide

• Le besoin de scalabilité horizontal est pris en compte dans la stack

Page 64: Run java vs ruby

Optimisation

• Stack complexe, donc complexe à optimiser– JVM– Serveur d’application– Frameworks– Application

Gain en performances significatif en optimisant la stack sous l’application

• Stack plus simple

Les gains en performances sont recherchés sur l’application

Page 65: Run java vs ruby

SUPERVISION / OUTILLAGE

Page 66: Run java vs ruby

SupervisionOutillage

• Visual VM• JMX• Profiling• Debugging à distance• Memory analyzer• …

Page 67: Run java vs ruby

SupervisionOutillage

• 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

Page 68: Run java vs ruby

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

Page 69: Run java vs ruby

CONCLUSION

Page 70: Run java vs ruby

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