SlideShare a Scribd company logo
1 of 70
Download to read offline
Retour d’expérience
  Applications web
Run Java vs Run Ruby

     bpa@octo.com
De quoi on parle ?
          Une application web
Clients




                  Serveur

               Application web




                  Base de
                  données
Sommaire
•   Les langages
•   Les application web
•   Le déploiement
•   La gestion des dépendances
•   Scalabilité
LES LANGAGES
• Langage « mainstream » • Langage non
• Compilé                  « mainstream »
• Statiquement typé      • 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 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
Avantages
•   Langage hyper expressif
•   Adapté au scripting
•   Plus simple (notamment réutilisation)
•   Plus « 2011 »
    – gem install heroku
    – rvm
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]
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 …
APPLICATION WEB
Application Web
                         Java
 code source


               compilation
.java                        .class



                                             déploiement
                                      .war
        .jar


.jsp




        .css
        .jpg
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
Stack Java
                                  standard
war1

        Application 1


   Framework web 1


                                           Queue
   javax.servlet
                                          Annuaire      Jboss, Weblogic, Websphere

       Stack HTTP Java
                                        EJB Container
                  Serveur d’application

                         Frontal HTTP                   Apache2, Nginx
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
Stack Java NG
• Nouvelles stacks qui apparaissent
  – Netty : asynchronisme
  – Play! : plus de javax.servlet
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
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
Application Web
                    Ruby
code source



  .rb




                     déploiement




  .erb




  .css
  .jpg
Stack ruby

        Application


     Framework web            Rails, Sinatra


Rack (API + Implémentation)


Serveur d’application Ruby    Unicorn, Passenger, Thin




       Frontal HTTP           Apache2, Nginx
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
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
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
Sessions HTTP
• Rails : Plusieurs types de session store
  – Cookies (défaut)
  – FileSystem
  – Memcache
  – DB
  –…
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
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
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
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 domaine
SSL compliqué à mettre en place

Difficile de faire www.octo.com/myApp
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
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
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
Application
                      Web

 • Stack web relativement proche




• Stack « veillissante » en   • Stack ruby un peu
  évolution                     moins lourde
GESTION DES DÉPENDANCES
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>
Dépendances
              Java
                      JVM
              Serveur d’application
Application (war)

WEB-INF/classes


  WEB-INF/lib



           lib du serveur d’application


                     lib JDK
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
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
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
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                           …
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
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
DÉPLOIEMENT
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
Pré requis serveur
•   Un OS
•   Un JDK (packagé avec l’OS)
•   Un serveur d’application
•   Eventuellement un serveur web

Relativement simple
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
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
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
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
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
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
                              Load balancer




               Frontal HTTP                   Frontal HTTP


              Serveur d’app                   Serveur d’app
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 deploy
                             Unicorn
$ pgrep -lf unicorn_rails
12113 unicorn_rails master -c   config/unicorn.rb -D
12118 unicorn_rails worker[0]   -c config/unicorn.rb -D
12136 unicorn_rails worker[1]   -c config/unicorn.rb -D
12137 unicorn_rails worker[2]   -c config/unicorn.rb -D


$ kill -s USR2 12113

$ pgrep -lf unicorn_rails
12113 unicorn_rails master (old) -c config/unicorn.rb -D
12118 unicorn_rails worker[0] -c config/unicorn.rb -D
12136 unicorn_rails worker[1] -c config/unicorn.rb -D
12137 unicorn_rails worker[2] -c config/unicorn.rb -D
12239 /usr/bin/ruby1.8 /usr/bin/unicorn_rails -c config/unicorn.rb -D

$ pgrep -lf unicorn_rails
12239 unicorn_rails master -c config/unicorn.rb -D
12245 unicorn_rails worker[0] -c config/unicorn.rb -D
12246 unicorn_rails worker[1] -c config/unicorn.rb -D
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
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
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
SCALABILITÉ
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
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
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
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
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
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
SUPERVISION / OUTILLAGE
Supervision
                   Outillage
•   Visual VM
•   JMX
•   Profiling
•   Debugging à distance
•   Memory analyzer
•   …
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
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

More Related Content

What's hot

Intellicore Tech Talk 10 - Apache Web Server Internals
Intellicore Tech Talk 10 - Apache Web Server InternalsIntellicore Tech Talk 10 - Apache Web Server Internals
Intellicore Tech Talk 10 - Apache Web Server InternalsNeil Armstrong
 
Rouabhi algiers meetup
Rouabhi algiers meetupRouabhi algiers meetup
Rouabhi algiers meetupSamir Rouabhi
 
Spring 3 en production
Spring 3 en productionSpring 3 en production
Spring 3 en productionJulien Dubois
 
GWT Principes & Techniques
GWT Principes & TechniquesGWT Principes & Techniques
GWT Principes & TechniquesRachid NID SAID
 
Présentation de Apache Zookeeper
Présentation de Apache ZookeeperPrésentation de Apache Zookeeper
Présentation de Apache ZookeeperMichaël Morello
 
Initiation à Express js
Initiation à Express jsInitiation à Express js
Initiation à Express jsAbdoulaye Dieng
 
Au coeur du framework .net 4.5.1
Au coeur du framework .net 4.5.1Au coeur du framework .net 4.5.1
Au coeur du framework .net 4.5.1Cellenza
 
Presentation Tomcat Load Balancer
Presentation Tomcat Load BalancerPresentation Tomcat Load Balancer
Presentation Tomcat Load Balancertarkaus
 
Paris Kafka Meetup - Concepts & Architecture
Paris Kafka Meetup - Concepts & ArchitectureParis Kafka Meetup - Concepts & Architecture
Paris Kafka Meetup - Concepts & ArchitectureFlorian Hussonnois
 
I le langage java d'una manière avancée introduction
I  le langage java d'una manière avancée introductionI  le langage java d'una manière avancée introduction
I le langage java d'una manière avancée introductionsabrine_hamdi
 
ToulouseJUG - REX Flex, Spring & Agilité
ToulouseJUG - REX Flex, Spring & AgilitéToulouseJUG - REX Flex, Spring & Agilité
ToulouseJUG - REX Flex, Spring & AgilitéNicolas Deverge
 
Une visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs Web
Une visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs WebUne visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs Web
Une visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs WebFrédéric Harper
 
Cours 1/3 "Architecture Web"
Cours 1/3 "Architecture Web"Cours 1/3 "Architecture Web"
Cours 1/3 "Architecture Web"Adyax
 

What's hot (20)

Intellicore Tech Talk 10 - Apache Web Server Internals
Intellicore Tech Talk 10 - Apache Web Server InternalsIntellicore Tech Talk 10 - Apache Web Server Internals
Intellicore Tech Talk 10 - Apache Web Server Internals
 
APACHE TOMCAT
APACHE TOMCATAPACHE TOMCAT
APACHE TOMCAT
 
Rouabhi algiers meetup
Rouabhi algiers meetupRouabhi algiers meetup
Rouabhi algiers meetup
 
Cours JSP
Cours JSPCours JSP
Cours JSP
 
Spring 3 en production
Spring 3 en productionSpring 3 en production
Spring 3 en production
 
GWT Principes & Techniques
GWT Principes & TechniquesGWT Principes & Techniques
GWT Principes & Techniques
 
Spring Batch ParisJUG
Spring Batch ParisJUG Spring Batch ParisJUG
Spring Batch ParisJUG
 
Présentation de Apache Zookeeper
Présentation de Apache ZookeeperPrésentation de Apache Zookeeper
Présentation de Apache Zookeeper
 
The Future of Javascript
The Future of JavascriptThe Future of Javascript
The Future of Javascript
 
Spring Batch - concepts de base
Spring Batch - concepts de baseSpring Batch - concepts de base
Spring Batch - concepts de base
 
Initiation à Express js
Initiation à Express jsInitiation à Express js
Initiation à Express js
 
Au coeur du framework .net 4.5.1
Au coeur du framework .net 4.5.1Au coeur du framework .net 4.5.1
Au coeur du framework .net 4.5.1
 
APACHE HTTP
APACHE HTTPAPACHE HTTP
APACHE HTTP
 
Presentation Tomcat Load Balancer
Presentation Tomcat Load BalancerPresentation Tomcat Load Balancer
Presentation Tomcat Load Balancer
 
Paris Kafka Meetup - Concepts & Architecture
Paris Kafka Meetup - Concepts & ArchitectureParis Kafka Meetup - Concepts & Architecture
Paris Kafka Meetup - Concepts & Architecture
 
I le langage java d'una manière avancée introduction
I  le langage java d'una manière avancée introductionI  le langage java d'una manière avancée introduction
I le langage java d'una manière avancée introduction
 
ToulouseJUG - REX Flex, Spring & Agilité
ToulouseJUG - REX Flex, Spring & AgilitéToulouseJUG - REX Flex, Spring & Agilité
ToulouseJUG - REX Flex, Spring & Agilité
 
Apache Maven 3
Apache Maven 3Apache Maven 3
Apache Maven 3
 
Une visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs Web
Une visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs WebUne visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs Web
Une visite guidée d’Internet Explorer 9 et HTML5 pour les développeurs Web
 
Cours 1/3 "Architecture Web"
Cours 1/3 "Architecture Web"Cours 1/3 "Architecture Web"
Cours 1/3 "Architecture Web"
 

Viewers also liked

Basic spanish structure
Basic spanish structureBasic spanish structure
Basic spanish structurekmeza
 
Likes and Dislikes
Likes and DislikesLikes and Dislikes
Likes and Dislikeskmeza
 
Basic conversational spanish
Basic conversational spanishBasic conversational spanish
Basic conversational spanishkmeza
 
El mundo del español 2
El mundo del español 2El mundo del español 2
El mundo del español 2kmeza
 
Spanish pronunciation
Spanish pronunciationSpanish pronunciation
Spanish pronunciationkmeza
 
Hispanic Culture *
Hispanic Culture *Hispanic Culture *
Hispanic Culture *kmeza
 

Viewers also liked (8)

Basic spanish structure
Basic spanish structureBasic spanish structure
Basic spanish structure
 
Likes and Dislikes
Likes and DislikesLikes and Dislikes
Likes and Dislikes
 
Basic conversational spanish
Basic conversational spanishBasic conversational spanish
Basic conversational spanish
 
El mundo del español 2
El mundo del español 2El mundo del español 2
El mundo del español 2
 
Autos 0 km
Autos 0 kmAutos 0 km
Autos 0 km
 
Enrique Guitart
Enrique GuitartEnrique Guitart
Enrique Guitart
 
Spanish pronunciation
Spanish pronunciationSpanish pronunciation
Spanish pronunciation
 
Hispanic Culture *
Hispanic Culture *Hispanic Culture *
Hispanic Culture *
 

Similar to Run java vs ruby

Architecture jee principe de inversion de controle et injection des dependances
Architecture jee principe de inversion de controle et injection des dependancesArchitecture jee principe de inversion de controle et injection des dependances
Architecture jee principe de inversion de controle et injection des dependancesENSET, Université Hassan II Casablanca
 
Les ZAPeroTech #4 : REX Oracle Code One 2019 sur l'éco-système Java
Les ZAPeroTech #4 : REX Oracle Code One 2019 sur l'éco-système JavaLes ZAPeroTech #4 : REX Oracle Code One 2019 sur l'éco-système Java
Les ZAPeroTech #4 : REX Oracle Code One 2019 sur l'éco-système JavaDocDoku
 
Parisweb - javascript server side - par où commencer ?
Parisweb - javascript server side - par où commencer ?Parisweb - javascript server side - par où commencer ?
Parisweb - javascript server side - par où commencer ?Quentin Adam
 
Node.js et les nouvelles technologies javascript
Node.js et les nouvelles technologies javascriptNode.js et les nouvelles technologies javascript
Node.js et les nouvelles technologies javascriptKhalid Jebbari
 
Appalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPAppalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPYouness Boukouchi
 
Session GWT Devoxx France 2012 Cobra
Session GWT Devoxx France 2012 CobraSession GWT Devoxx France 2012 Cobra
Session GWT Devoxx France 2012 CobraDNG Consulting
 
Gwt oxiane-novae-lr
Gwt oxiane-novae-lrGwt oxiane-novae-lr
Gwt oxiane-novae-lroxmed
 
Pourquoi rails est génial? (version longue)
Pourquoi rails est génial? (version longue)Pourquoi rails est génial? (version longue)
Pourquoi rails est génial? (version longue)Camille Roux
 
03 - [ASP.NET Core] Services RESTful et SPA
03 - [ASP.NET Core] Services RESTful et SPA 03 - [ASP.NET Core] Services RESTful et SPA
03 - [ASP.NET Core] Services RESTful et SPA Cellenza
 
Introduction aux RIA (Rich Internet Applications)
Introduction aux RIA (Rich Internet Applications)Introduction aux RIA (Rich Internet Applications)
Introduction aux RIA (Rich Internet Applications)Tugdual Grall
 
2014.12.11 - TECH CONF #3 - Présentation Node.js
2014.12.11 - TECH CONF #3 - Présentation Node.js2014.12.11 - TECH CONF #3 - Présentation Node.js
2014.12.11 - TECH CONF #3 - Présentation Node.jsTelecomValley
 
Autour de Node.js - TechConf#3
Autour de Node.js - TechConf#3Autour de Node.js - TechConf#3
Autour de Node.js - TechConf#3Luc Juggery
 
technologie web - part3
technologie web - part3technologie web - part3
technologie web - part3Benoît Simard
 
Realtime Web avec Kafka, Spark et Mesos
Realtime Web avec Kafka, Spark et MesosRealtime Web avec Kafka, Spark et Mesos
Realtime Web avec Kafka, Spark et Mesosebiznext
 
cours-gratuit.com--id-1964.pdf
cours-gratuit.com--id-1964.pdfcours-gratuit.com--id-1964.pdf
cours-gratuit.com--id-1964.pdfRachida19
 

Similar to Run java vs ruby (20)

Formation Google App Engine
Formation Google App EngineFormation Google App Engine
Formation Google App Engine
 
Architecture jee principe de inversion de controle et injection des dependances
Architecture jee principe de inversion de controle et injection des dependancesArchitecture jee principe de inversion de controle et injection des dependances
Architecture jee principe de inversion de controle et injection des dependances
 
FinistJUG - Apache TomEE
FinistJUG - Apache TomEEFinistJUG - Apache TomEE
FinistJUG - Apache TomEE
 
Support NodeJS avec TypeScript Express MongoDB
Support NodeJS avec TypeScript Express MongoDBSupport NodeJS avec TypeScript Express MongoDB
Support NodeJS avec TypeScript Express MongoDB
 
Les ZAPeroTech #4 : REX Oracle Code One 2019 sur l'éco-système Java
Les ZAPeroTech #4 : REX Oracle Code One 2019 sur l'éco-système JavaLes ZAPeroTech #4 : REX Oracle Code One 2019 sur l'éco-système Java
Les ZAPeroTech #4 : REX Oracle Code One 2019 sur l'éco-système Java
 
Parisweb - javascript server side - par où commencer ?
Parisweb - javascript server side - par où commencer ?Parisweb - javascript server side - par où commencer ?
Parisweb - javascript server side - par où commencer ?
 
Node.js et les nouvelles technologies javascript
Node.js et les nouvelles technologies javascriptNode.js et les nouvelles technologies javascript
Node.js et les nouvelles technologies javascript
 
Appalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPAppalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSP
 
Session GWT Devoxx France 2012 Cobra
Session GWT Devoxx France 2012 CobraSession GWT Devoxx France 2012 Cobra
Session GWT Devoxx France 2012 Cobra
 
Java Entreprise Edition
Java Entreprise EditionJava Entreprise Edition
Java Entreprise Edition
 
La plateforme JEE
La plateforme JEELa plateforme JEE
La plateforme JEE
 
Gwt oxiane-novae-lr
Gwt oxiane-novae-lrGwt oxiane-novae-lr
Gwt oxiane-novae-lr
 
Pourquoi rails est génial? (version longue)
Pourquoi rails est génial? (version longue)Pourquoi rails est génial? (version longue)
Pourquoi rails est génial? (version longue)
 
03 - [ASP.NET Core] Services RESTful et SPA
03 - [ASP.NET Core] Services RESTful et SPA 03 - [ASP.NET Core] Services RESTful et SPA
03 - [ASP.NET Core] Services RESTful et SPA
 
Introduction aux RIA (Rich Internet Applications)
Introduction aux RIA (Rich Internet Applications)Introduction aux RIA (Rich Internet Applications)
Introduction aux RIA (Rich Internet Applications)
 
2014.12.11 - TECH CONF #3 - Présentation Node.js
2014.12.11 - TECH CONF #3 - Présentation Node.js2014.12.11 - TECH CONF #3 - Présentation Node.js
2014.12.11 - TECH CONF #3 - Présentation Node.js
 
Autour de Node.js - TechConf#3
Autour de Node.js - TechConf#3Autour de Node.js - TechConf#3
Autour de Node.js - TechConf#3
 
technologie web - part3
technologie web - part3technologie web - part3
technologie web - part3
 
Realtime Web avec Kafka, Spark et Mesos
Realtime Web avec Kafka, Spark et MesosRealtime Web avec Kafka, Spark et Mesos
Realtime Web avec Kafka, Spark et Mesos
 
cours-gratuit.com--id-1964.pdf
cours-gratuit.com--id-1964.pdfcours-gratuit.com--id-1964.pdf
cours-gratuit.com--id-1964.pdf
 

Run java vs ruby

  • 1. Retour d’expérience Applications web Run Java vs Run Ruby bpa@octo.com
  • 2. De quoi on parle ? Une application web Clients Serveur Application web Base de données
  • 3. Sommaire • Les langages • Les application web • Le déploiement • La gestion des dépendances • Scalabilité
  • 5. • Langage « mainstream » • Langage non • Compilé « mainstream » • Statiquement typé • Interprété • Dynamiquement typé
  • 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 …
  • 12. Application Web Java code source compilation .java .class déploiement .war .jar .jsp .css .jpg
  • 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. Stack Java standard war1 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. 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
  • 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. Application Web Ruby code source .rb déploiement .erb .css .jpg
  • 20. Stack ruby Application Framework web Rails, Sinatra Rack (API + Implémentation) Serveur d’application Ruby Unicorn, Passenger, Thin Frontal HTTP Apache2, Nginx
  • 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
  • 29. Url • myApp.octo.com Une application par domaine SSL compliqué à mettre en place Difficile de faire www.octo.com/myApp
  • 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
  • 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. Dépendances Java JVM Serveur d’application Application (war) WEB-INF/classes WEB-INF/lib lib du serveur d’application lib JDK
  • 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
  • 54. Hot deploy Unicorn $ pgrep -lf unicorn_rails 12113 unicorn_rails master -c config/unicorn.rb -D 12118 unicorn_rails worker[0] -c config/unicorn.rb -D 12136 unicorn_rails worker[1] -c config/unicorn.rb -D 12137 unicorn_rails worker[2] -c config/unicorn.rb -D $ kill -s USR2 12113 $ pgrep -lf unicorn_rails 12113 unicorn_rails master (old) -c config/unicorn.rb -D 12118 unicorn_rails worker[0] -c config/unicorn.rb -D 12136 unicorn_rails worker[1] -c config/unicorn.rb -D 12137 unicorn_rails worker[2] -c config/unicorn.rb -D 12239 /usr/bin/ruby1.8 /usr/bin/unicorn_rails -c config/unicorn.rb -D $ pgrep -lf unicorn_rails 12239 unicorn_rails master -c config/unicorn.rb -D 12245 unicorn_rails worker[0] -c config/unicorn.rb -D 12246 unicorn_rails worker[1] -c config/unicorn.rb -D
  • 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