Profiler une requête rails
Pour découvrir le bug dont j'ai reporté précédement les effets, j'ai voulu réaliser un profile de la requête executée. Ca devait me permettre de voir ce qui prenait vraiment beaucoup de temps dans l'execution de cette page.
Utilisation du script Request Profiler
Depuis Rails 2.0, un nouveau script a été ajouté,
script/performance/request. Ce script permet de réaliser un
profile d'une ou plusieurs requête internet.
Pour indiquer les requêtes à executer il suffit de réaliser un petit fichier de script avec le même format que les tests d'intégrations. Voici un exemple issue du changelog de rails.
get_with_redirect '/' say "GET / => #{path}" post_with_redirect '/sessions', :username => 'john', :password => 'doe' say "POST /sessions => #{path}"
Une fois le script réalisé, il suffit de lancer la commande en définissant le nombre de requêtes qui seront effectuées
$ ./script/performance/request -n 10 login_session.rb
Par contre, il faut faire très attention, il n'y a aucune solution (ou tout du moins à ma connaissance) pour définir les valeurs de la session. La session est vierge à chaque lancement de script. Il faut donc réaliser la connection de login au préalable pour avoir un utilisateur loggé par exemple.
Incompatibilité Rails 2.1 et ruby-prof
Alors que j'avais indiqué l'ajout d'un nouveau script dans Rails Edge qui nécessitait ruby-prof 0.6.1, je pensais que c'était le seul endroit qui nécessitait cette version de ruby-prof qui n'existe pas encore (dernière version stable : 0.6.0 en téléchargement sur rubyforge). Hélas, ce n'est pas le cas. Depuis la version 2.1 de Rails, le script performance/request nécessite aussi ruby-prof 0.6.1. Mais cette version, n'est toujours pas encore sortie officielement. Il faut donc générer et installer ce gem pour arriver à avoir cette fonctionnalité. En effet, même en modifiant la version de ruby-prof des méthodes n'existent pas dans les versions antérieurs à la version 0.6.1
Génération et installation de ruby-prof-0.6.1
Il faut d'abord récupérer les sources directements à partir du svn de ruby-prof
svn co http://ruby-prof.rubyforge.org/svn/
Ensuite, il faut générer le gem
$ rake package
Enfin, il suffit d'installer le gem.
# gem install pkg/ruby-prof-0.6.1.gem
Désormais, ruby-prof 0.6.1 est installé et vous pouvez utiliser pleinement le script performance/request.
[...]Thin, le buzz qui se justifie
C'est quoi Thin ?
Depuis maintenant 3 mois seulement un nouveau gem est apparu comme webserver. Sa logique est simple. Prendre tout ce qu'il y a de meilleur partout, de compiler tout çà et d'en faire un meilleur produit. Ce gem, c'est Thin. Il se dit "Yet Another WebServer". Je pense que le titre est en référence à YARV. Mais je n'en ai aucune preuve.
Depuis la version 0.7.0 de thin, le buzz a pris de l'ampleur sur les bienfaits de ce WebServer. Étant un peu aventurier, j'ai décidé de tenter l'aventure. J'ai migré mes 3 applications de mongrel_cluster vers Thin. Voici donc comment faire cette migration car il n'y a rien de plus simple.
Installer Thin
Il faut déjà installer le gem thin
#gem install thin
Le meilleur moyen pour lancer les commandes de lancement de Thin, il faut allez dans le répertoire de son application Rails. Dans ce répertoire, faire :
$thin config -C config/thin.yml
Avec cette commande thin va préparer un fichier de configuration complet il ne vous restera plus qu'à le modifier. J'ai mis ce fichier dans config/thin.yml pour être homogène avec mongrel_cluster. Il n'y a aucune obligation de nomage ou d'emplacement. Le fichier de base est du type suivant :
--- pid: tmp/pids/thin.pid log: log/thin.log port: 3000 max_conns: 1024 timeout: 30 environment: development max_persistent_conns: 512 chdir: /var/rails/typo-5-0-stable address: 0.0.0.0
Il ressemble ainsi très fortement au fichier de mongrel_cluster.yml. Il ne reste plus qu'a le modifier pour qu'il fasse ce que l'on souhaite. En général, on modifie le port et l'environnement. Ensuite, on peux définir le nombre d'instance de thin dédiés à cette application. Pour cela on a juste à rajouter la clé servers: et donner le nombre d'instance. Mon fichier est ainsi devenu :
--- pid: tmp/pids/thin.pid log: log/thin.log port: 44000 max_conns: 1024 timeout: 30 environment: production max_persistent_conns: 512 chdir: /var/rails/typo-5-0-stable address: 0.0.0.0 servers: 2
Enfin pour démarrer ou arreter ces instances, rien de plus simple.
démarrage :
$ thin start -C config/thin.yml
arrêt :
$ thin stop -C config/thin.yml
Et maintenant l'intérêt ?
Intérêt de thin
Au niveau de la mémoire, il n'y a pas vraiment de différence entre mongrel et thin. Ils utilisent a peu près la même mémoire d'après ce que j'ai pu constater. Par contre, au niveau de la vitesse de réponse, thin est un peu plus rapide. Ainsi voici les résultats d'un benchmark rapide que j'ai réalisé sur ma dédibox.
Pour mongrel
hello:~/$ ab -n 1000 -c 10 http://dev.shingara.fr/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking dev.shingara.fr (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests
Server Software: nginx/0.6.26
Server Hostname: dev.shingara.fr
Server Port: 80
Document Path: /
Document Length: 4640 bytes
Concurrency Level: 10
Time taken for tests: 81.920747 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 4995000 bytes
HTML transferred: 4640000 bytes
Requests per second: 12.21 [#/sec] (mean)
Time per request: 819.207 [ms] (mean)
Time per request: 81.921 [ms] (mean, across all concurrent requests)
Transfer rate: 59.53 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 36 38 1.5 38 76
Processing: 94 778 726.4 644 4108
Waiting: 92 774 723.3 641 4106
Total: 131 816 726.4 681 4146
Percentage of the requests served within a certain time (ms)
50% 681
66% 1273
75% 1344
80% 1382
90% 1669
95% 1924
98% 2634
99% 3011
100% 4146 (longest request)
Pour thin
hello:~/$ ab -n 1000 -c 10 http://dev.shingara.fr/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking dev.shingara.fr (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests
Server Software: nginx/0.6.26
Server Hostname: dev.shingara.fr
Server Port: 80
Document Path: /
Document Length: 4640 bytes
Concurrency Level: 10
Time taken for tests: 67.245564 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 4986008 bytes
HTML transferred: 4646330 bytes
Requests per second: 14.87 [#/sec] (mean)
Time per request: 672.456 [ms] (mean)
Time per request: 67.246 [ms] (mean, across all concurrent requests)
Transfer rate: 72.41 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 36 44 133.9 38 3035
Processing: 93 621 462.3 518 1946
Waiting: 91 548 389.6 473 1665
Total: 132 666 483.9 561 4278
Percentage of the requests served within a certain time (ms)
50% 561
66% 878
75% 1017
80% 1098
90% 1309
95% 1580
98% 1703
99% 1795
100% 4278 (longest request)
Ca veux dire quoi ?
Il y a une petite avance pour thin qui permet de faire 14,87 requêtes par seconde contre 12,21 requêtes pour mongrel. Tout cela avec 10 instances simultanés et un total de 1000 requêtes. Mais après tout thin n'a que 3 mois. Il est encore jeune et n'a pas de version 1.0. Ça devrait pouvoir encore s'améliorer.
Coté parano ?
Je n'ai pas encore pu tester la stabilité de thin. En effet, on peux se demander à juste titre si il est vraiment stable. Pour cela il faudra attendre.
[...]Une bonne amélioration pour Firefox 3
Ca y est c'est officiel, Firefox sera meilleur en terme de fuite de mémoire et autre consommation excessive. On peux ainsi lire l'annonce sur le blog de Jesse Ruderman.
Cette annonce a ainsi été relayé par Slashdot et Tristan Nitot.
Je suis vraiment content que cette annonce ait été faite. En effet, j'aime beaucoup Firefox et surtout l'utilisation de ses nombreux plugins. Mais le fait de devoir régulièrement redémarrer cette application était un peu désagréable surtout avec l'utilisation actuelle de site internet de plus en plus puissance en terme de Javascript.
[...]replaceHTML plus rapide que innerHTML
Steven Levithan de RegexPal a réaliser une page qui permet de faire une comparaison de performance entre les deux méthodes Javascript innerHTML() et replaceHTML().
Grâce à cette page de benchmark, il prouve sans conteste qu'il faut de préférence utiliser la méthode replaceHTML que la méthode innerHTML. Bien sûr, certain cas impose d'utiliser innerHTML.
[...]