Améliorer les performances d’apache avec nginx

Plop à tous …

Comme vous l’aurez sûrement remarqué, la quasi-totalité de mes derniers articles sont tirés d’expériences (plutôt foireuses) me poussant souvent à remettre en questions certaines notions que je pensais acquises … cet article n’y coupera pas :s.

Après avoir vénéré les serveurs apache pendant 7 ans, j’ai eu récemment à m’asseoir sur mes convictions et à installer nginx pour avoir des performances convenables …

Note du 2016/02/20 : L’erreur a été d’installer apache en mod_prefork sur un environnement demandant de grosse perf, en utilisant un mpm_event avec un fcgi, ça marche très bien.

La question

Pour la petite histoire, on m’avait demandé si une dedibox premier prix (2gig de ram et 2ghz de CPU) pouvait supporter dans les 60000 visiteurs/jours, j’ai répondu d’un oui fier et franc tout en appuyant ma réponse avec un petit calcul :

60000 visiteurs/12 heures (la nuit y’a pas beaucoup de visite …) * 100 ressources / 60 / 60 = 138 connexions par secondes. (Ce qui ne devrait pas être un gros problème pour apache).
Donc au minimum la config apache devait avoir un StartServer à 150 et devait pouvoir monter à 500 en jouant sur les MinSpareServers et MaxSpareServers.

Après achat d’un serveur avec 4 gig de ram, et une rapide configuration, le serveur apache tourne, les transferts DNS sont effectués, et là 400 visiteurs arrivent … apache consomme toute la mémoire, le serveur swap, plus rien ne répond … c’est foutu, à l’arrache je passe le swapiness à 0 et je baisse le nombre de ThreadLimit à 80 (pour 4 gig de ram c’est le maximum que l’on peut avoir).

Et là, le site web ram … plus de 500 personnes tente de se connecter en simultanée …
Pragmatique et très calme, le propriétaire du serveur me sort un gentil : « C’est pas toi qui m’avait dit que ça tiendrait le choc ? ».

L’erreur

UPDATE 25/08/2012 : Le serveur installé était en mod « normal » (prefork), qui n’est pas fait pour de la prod (chaque fork possède l’ensemble des modules chargés en mémoire, d’où la surconsommation de mémoire, Apache reste très performant ;)). C’est l’admin qui l’a installé qui est mauvais ^^.
Ma grosse erreur a été de ne pas calculer la ram nécessaire pour cette configuration :
Un process apache consomme 50Meg (en moyenne avec un ThreadPerChild à 5) et 50Mo * 150 processus = 7500Mo de ram nécessaire rien que pour soutenir le nombre de connexions moyen (en soirée ça devait monter à 500!!), et plus de 20 Gig de ram pour supporter plus de 400 connexions secondes.

La solution

Au final j’ai donc du me tourner vers nginx en reverse proxy pour apache et en fournisseur de contenu statique, la config est faite en 5 minute :

Dans un fichier mis dans le dossier /etc/nginx/sites-enabled/, on créée le reverse proxy sur notre serveur apache (qui écoutera sur un autre port : 8080), et toute url qui se termine en jpg,js,png … est directement cherchée sur le disque et renvoyée au client sans passer par apache

server {
  listen 80;
  server_name www.monsite.fr monsite.fr *.monsite.fr;

  location / {
    proxy_pass http://127.0.0.1:8080/;
    access_log off;
  }

  location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|txt|xml)$ {
    root /var/www;
    access_log /var/log/nginx/monsite.fr.access.log;
    error_log /var/log/nginx/monsite.fr.errors.log;
    expires 30d;
  }
}

Pour apache on modifie le port d’écoute général :
Dans /etc/apache2/ports.conf

Listen 8080

Et on modifie tout les VirtualHost *:80 dans les fichiers contenu dans /etc/apache2/sites-enabled/ par VirtualHost *:8080

Après un redémarrage d’apache et nginx, le serveur n’utilise que 700Mo de ram pour gérer 500 connexions/secondes, apache n’utilise que 20 processus, et nginx ne consomme rien (aucun module n’a été installé sur nginx). Cela dit, utiliser un apache worker voir un event worker aurait pu « corriger » ce problème, mais n’étant pas sûr du résultat, et étant dans le feu de l’action, je n’ai pas eu le temps de trop chercher de solution (on dirait pas comme ça, mais c’est éprouvant la vie d’un sysadmin ;)).

Cela dit, le résultat est très probant, le wordpress et le forum sont affichés de façon quasi instantannées, et le serveur ne ram plus du tout.

8 réflexions sur « Améliorer les performances d’apache avec nginx »

  1. dans ce cas autant installer varnish si c’est pour passer le tout à apache, après pour une dedibox v1 le problème c’est pas vraiment la ram mais le processeur qui est vraiment faible, ducoup avec du php suivant le programme on se retrouve rapidement avec le processeur à 100% (suivant le nombre de req/sec)

  2. Toutes les requetes sur des fichiers statiques sont envoyes sur nginx.
    Il ne reste donc plus que les requetes sur les fichiers php ( et tous ceux qui ne rentre pas dans la regexp) a renvoyer sur apache. Ce qui reduit grandement son nombre de process.
    Donc dans mon cas cette architecture est suffisante et permet de parer la conso de ram d’apache.

  3. Côté module de sécurité, y’a pas grand chose (je viens cependant de découvrir un projet qui semble être l’équivalent du modsecurity), et je ne connais pas aussi bien nginx que apache, ensuite, le support du php est fait en cgi-bin, mode que je n’apprécie pas trop.

  4. Salut, j’ai voulu tester rapidos ce soir, mais ça me met des 404 sur les fichiers statiques.

    Une idée ?

    Merci

Les commentaires sont fermés.