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. 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. Avantages
• Langage hyper expressif
• Adapté au scripting
• Plus simple (notamment réutilisation)
• Plus « 2011 »
– gem install heroku
– rvm
9. Exemples
def chrono msg
start = Time.now.to_i
yield
puts "#{msg} : #{Time.now.to_i - start} sec"
end
chrono "Long operation" do
run_very_long_operation
end
class Integer
def hex
to_s(16)
end
end
12.Hex
=> "c"
[1, 4, 10].map{|x| 2 * x}.sort
=> [2, 8, 20]
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 …
15. requête HTTP
Parallélisme
Frontal HTTP
JVM
Stack HTTP Java
Thread worker 1
javax.servlet
choix d’un
thread worker
Application
Thread worker 2
Thread worker 3
Thread worker 4
Mémoire partagée entre les threads => session stockée en mémoire
16. Stack Java NG
• Nouvelles stacks qui apparaissent
– Netty : asynchronisme
– Play! : plus de javax.servlet
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
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. Mongrel
requête HTTP
port 1901 Mongrel 1 Rack Application
Frontal 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. Passenger
requête HTTP
Apache 2
Nginx Worker 1 Rack Application
Module 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. Sessions HTTP
• Rails : Plusieurs types de session store
– Cookies (défaut)
– FileSystem
– Memcache
– DB
–…
25. PHP
requête HTTP
Apache 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. 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. 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. 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
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. 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. 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. Application
Web
• Stack web relativement proche
• Stack « veillissante » en • Stack ruby un peu
évolution moins lourde
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
continue
Stocke l’artefact Nexus Dépôt d’entreprise
Proxy internet
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. 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. Dépendances
Ruby
Serveur d’application Gem Repository
Gem A v 1.1
Application
Gem B v 0.7
*.rb
Gem C v 1.9
*.rb …
41. Bibliothèques
spécifiques
Création Utilisation
Déclare l’utilisation de
Dé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. 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
44. Déploiement
Tomcat, Jetty, Jboss dépôt dans un dossier
.war
Jboss, Websphere appel d’une API sur le serveur d’application
.war
• Peut déployer sur un cluster
• Est en général long
45. Pré requis serveur
• Un OS
• Un JDK (packagé avec l’OS)
• Un serveur d’application
• Eventuellement un serveur web
Relativement simple
46. Déploiement
code 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. Déploiement
avec Capistrano
Serveur Gestion de
d’application configuration
checkout
current symlink
cap deploy
app_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. 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. Exemple
Skillstar
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
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 complexe
Exemple :
• rvm-shell default -c ‘RAILS_ENV=production bundle exec rake db:migrate’
• Installation de passenger qui recompile un module Nginx
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. 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. 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
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. 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. 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
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 commun
Thread 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
difficile
Base de données
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
workers
Worker 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. Scalabilité
multi machine
Load balancer
Frontal HTTP Frontal HTTP Frontal HTTP
Serveur 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. Scalabilité
multi machine
Load balancer
Frontal HTTP Frontal HTTP Frontal HTTP
Serveur 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. 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. 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
66. Supervision
Outillage
• Visual VM
• JMX
• Profiling
• Debugging à distance
• Memory analyzer
• …
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. 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
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