4 strates à changer pour accélérer une app Ruby on Rails

Le framework Ruby on Rails est livré avec son propre serveur Web, appelé Webrick, mais il est souvent nécessaire d’avoir des VirtualHosts afin d’héberger plusieurs sites sur un même port. Nous allons voir quels sont les choix techniques qui s’offrent à nous.

1- Remplacer le serveur Web applicatif

Comme énoncé en introduction, Webrick est le serveur Web livré par défaut avec Ruby on Rails pour exécuter nos applications. Il existe de nombreuses alternatives telles qu’Unicorn ou Puma, cependant Phusion Passenger est celle qui est recommandée par les auteurs de RoR pour un passage en production.

Phusion Passenger est notablement plus rapide que ses concurrents :

Phusion PassengerCe projet Libre met en avant sa capacité à multi-threader le traitement des requêtes et à générer son propre cache, offrant ainsi de meilleures performances. Il est disponible en module pour Apache et Nginx.

2- Choisir un serveur Web frontal

Il est fréquent de souhaiter héberger plusieurs applications derrière la même adresse IP et sur un même port (80), parfois dans des langages différents. Le recourt à un serveur aussi spécialisé que Phusion Passenger rendrait cette cohabitation impossible. La solution consiste à intercaler un serveur Web entre les internautes et le serveur Web applicatif.

Apache est un serveur Web multiplateforme, capable de servir des fichiers statiques et de déléguer l’exécution de code source à un module. S’il est très répandu et occupe aux alentours de 40% de parts de marché, il n’est cependant pas réputé pour sa légèreté ni pour sa rapidité.

Heureusement la diversité ne manque pas, Nginx (prononcer « engine ex ») est un concurrent sérieux, qui avoisine 15% de parts de marché. Simple, robuste, léger et très rapide, son fonctionnement diffère de celui d’Apache tout en se configurant de manière presque identique.

Performances

Lors de chaque requête HTTP qu’Apache reçoit, un nouveau thread est créé. Ce comportement occasionne certains désagréments, comme un ralentissement dans le traitement des requêtes au fil du temps.

De son côté, Nginx reçoit d’abord toutes les requêtes dans le même thread, puis créé des threads par paliers au fur et à mesure de la montée en charge. Cela a pour effet une consommation en Ram presque linéaire et une rapidité de traitement plus élevée qu’Apache.

Ces constats ne sont toutefois vérifiables qu’en charge significative, par exemple dans ce benchmark daté de 2008 observant le cas précis de la distribution de fichiers statiques pour 3500 connexions simultanées :
– Apache traite 2500 requêtes / seconde pour 35Mo de Ram
– Nginx traite 9500 requêtes / seconde pour 2,5Mo de Ram

Nginx a par ailleurs été choisi par WordPress.com car c’était le seul serveur capable de traiter 10M de requêtes / jour (soit plus de 8000 par seconde) ainsi que pour sa stabilité. Apache a été corrigé et optimisé dans sa version 2.4 mais conserve toujours la même architecture.

Fonctionnalités

D’un point de vue configuration, Apache et Nginx proposent une syntaxe semblable, bien que plus simple dans le cas d’Nginx. La rédaction de VirtualHost est très proche, ces derniers étant rangés dans les deux cas dans des répertoires appelés « sites-availables » et « sites-enabled ». Les deux serveurs disposent de modules parfois communs, comme par exemple Passenger qui permet d’exécuter du code Ruby.

3- Utiliser une solution de cache

Après avoir optimisé notre code source, il devient envisageable de faire intervenir un système de cache au niveau applicatif.

En fonction du dynamisme de l’application, la fréquence de rafraichissement du cache peut varier de quelques minutes à plusieurs mois. Par exemple, la page produit d’un site d’e-commerce ne sera regénérée que lors d’un achat, afin de changer le décompte du stock. La partie publique aurait tout intérêt à être rendue statique au format HTML.

La génération d’un cache de ce type peut être réalisé avec la gem développée par l’équipe de RoR, appelée actionpack-page_caching.

4- Ajouter un reverse proxy

Il est possible d’étudier une solution spécifique pour servir nos fichiers statiques plus rapidement qu’avec notre serveur Web frontal. Cette solution ne semble pas particulièrement intéressante au premier abord, car le plus grand du temps de génération d’une page provient des algorithmes mis en œuvre dans notre application Ruby on Rails.

Mais avec l’utilisation d’une gem telle que décrite dans le chapitre précédent, notre site n’a plus besoin d’être dynamique la plupart du temps.

C’est à ce moment que le serveur Varnish entre en jeu :

Varnish-Nginx-PassengerVarnish est un reverse-proxy optimisé pour servir des fichiers statiques. Dans cette configuration, il interceptera les requêtes sur le port 80 et les transfèrera à Nginx sur un autre port. La gestion des VirtualHost reste sur Nginx bien que nécessitant une rapide adaptation.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.