Date post: | 27-Jun-2015 |
Category: |
Documents |
Upload: | pinguin666 |
View: | 1,239 times |
Download: | 0 times |
De quoi on parle ?Une application web
Serveur
Base de données
Application web
Clients
Sommaire
• Les langages• Les application web• Le déploiement• La gestion des dépendances• Scalabilité
LES LANGAGES
• Langage « mainstream »• Compilé• Statiquement typé
• Langage non « mainstream »
• Interprété• Dynamiquement typé
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
Virtual MachineJava
• Oracle : Hotspot– Open JDK
• IBM– Utilisée avec Websphere
• BEA : jRockit
Principales différences au niveau du GCConvergence sur Hotspot et OpenJDK
Avantages
• Langage hyper expressif• Adapté au scripting• Plus simple (notamment réutilisation)• Plus « 2011 »– gem install heroku– rvm
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é
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 …
APPLICATION WEB
Application WebJava
.java
.jsp
.css
.jpg
.jar
.class
.war
compilation
déploiement
code source
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
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
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
Stack Java NG
• Nouvelles stacks qui apparaissent– Netty : asynchronisme– Play! : plus de javax.servlet
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
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
Application WebRuby
.rb
.erb
.css
.jpg
déploiement
code source
Stack ruby
Serveur d’application Ruby
Frontal HTTP Apache2, Nginx
Unicorn, Passenger, Thin
Rack (API + Implémentation)
Framework web Rails, Sinatra
Application
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
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
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
Sessions HTTP
• Rails : Plusieurs types de session store– Cookies (défaut)– FileSystem– Memcache– DB– …
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
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
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
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
Url
• myApp.octo.com
Une application par domaineSSL compliqué à mettre en place
Difficile de faire www.octo.com/myApp
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
• 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
• 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
• Stack « veillissante » en évolution
• Stack ruby un peu moins lourde
ApplicationWeb
• Stack web relativement proche
GESTION DES DÉPENDANCES
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>
JVM
Serveur d’application
DépendancesJava
Application (war)
WEB-INF/lib
WEB-INF/classes
lib du serveur d’application
lib JDK
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
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
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
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
…
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
• 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
DÉPLOIEMENT
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
Pré requis serveur
• Un OS• Un JDK (packagé avec l’OS)• Un serveur d’application• Eventuellement un serveur web
Relativement simple
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
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
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
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
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
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 »
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
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
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
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
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
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
SCALABILITÉ
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
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
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
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
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
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
SUPERVISION / OUTILLAGE
SupervisionOutillage
• Visual VM• JMX• Profiling• Debugging à distance• Memory analyzer• …
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
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
CONCLUSION
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