Apache a 25 ans, mais le connaissez-vous vraiment ?

le mardi 18 février 2020

Bearstech | Dernière mise à jour : mardi 18 février 2020

Apache, c'est un peu le papy des serveurs HTTP, mais il a toujours de quoi botter l'arrière train de quelques jeunots.

Apache a 25 ans et il est toujours fortement implanté, bien que Netcraft semble indiquer un net recul depuis son hégémonie indiscutable jusqu'en 2014 . Mais c'est précisément la période ou les CDNs et les reverse-proxies (Varnish, Traefik,etc.) ont explosé, rendant ce paysage plus complexe à appréhender.

logo fondation Apache

On ne devrait plus dire "Apache" mais le projet "Apache httpd", car depuis la création de la Fondation Apache en 1999 comme organe de gouvernance du projet, de nombreux autres logiciels ont été incubés ou recueillis par la fondation (comme les fameux ActiveMQ, Cassandra, Lucene, etc.). Mais l'habitude est restée et personne ne vous en voudra de confondre le serveur HTTP et la fondation qui héberge près de 350 projets libres.

L'inventeur du ".htaccess"

On l'aime ou on le déteste, mais la possibilité de customiser le comportement du serveur HTTP sans en être administrateur, le faire finement, de façon sécurisée (comprendre : vous pouvez planter votre site, mais vous ne planterez pas celui du voisin sur le même serveur) via le ".htaccess" est ingénieuse et a permis de s'adapter à des foules de situations diverses et variées sans douleur, évitant probablement des milliers de guerres thermonucléaires entre adminsys et webdevs.

Aujourd'hui les applications et les développeurs ont les mêmes besoins de contrôle de l'amont en HTTP, mais vont plutôt utiliser des APIs - à l'instar de Traefik ou Haproxy. Mais avec son inertie, son parc déployé et sa culture étalée sur une génération, le ".htacess" va être la lingua franca de la configuration HTTP du web pour encore un moment. Si vous passez une journée sur mod_rewrite(https://httpd.apache.org/docs/current/mod/mod_rewrite.html), dites-vous que ça ne sera pas gâché...

Le A de LAMP

Qui dit Apache, dit historiquement PHP dans le coin. Apache était bien conçu pour embarquer des interpréteurs tiers (Tcl, Perl, PHP, Python, etc.) et a accueilli tout le monde sans discrimination. Il faut comprendre que c'est un facteur clé pour au moins deux bonnes raisons.

La première concerne la facilité de déploiement : activer un interpréteur embarqué dans Apache c'est en général (aussi grâce au travail de sa distribution) aussi simple qu'appuyer sur l'interrupteur du plafonnier : on active le module, et fiat lux ! Par ailleurs si Apache permet plusieurs modes d'intégration, il a tout de suite permis d'associer une extension à un interpréteur, ce qui était à la fois intuitif (c'est celui de la métaphore du "desktop") et efficace.

La seconde relève de la performance : jusqu'ici les serveurs HTTP utilisaient le modèle CGI qui consiste à lancer un nouvel interpréteur pour chaque requête. Or créer un nouveau processus c'est alors coûteux, et charger le code et les bibliothèques de la plupart des interpréteurs assez long; ajoutez l'absence de serveurs multi-processeurs jusqu'au milieu des années 2000, c'était peu véloce et surtout gérait très mal plusieurs accès simultanés. Apache en lançant à l'avance plusieurs processus avec des interpréteurs déjà chargés et près à compiler et exécuter votre requête dès la première milliseconde s'est assuré un succès sans faille pendant au moins 10 ans.

Passage à l'échelle

Dans les années 2000 le paradigme d'Apache - bien qu'efficace et en pleine gloire et expansion - est déjà critiqué par les quelques sites qui commencent à avoir des trafics hors du commun. Un papier séminal - "The C10K problem" - en fait une superbe analyse et propose des solutions, qui vont rapidement être implémentées dans le monde Unix.

Apache a hérité du mode de pensée Unix : un processus encapsule une unité de travail, pour un utilisateur donné. Cela permet de garantir un très bon niveau de sécurité, et une facilité de programmation incomparable : on écrit son programme comme si on avait à faire à un seul utilisateur, de façon linéaire et prévisible, puis on demande à l'OS de multiplier les processus comme des petits pains et le tour est joué, on a un site ecommerce à succès. Sauf que ces processus ont des coûts incompressibles, bien que Linux en particulier soit arrivé à des trésors d'optimisations stupéfiants. Et surtout les utilisateurs sont nombreux et dynamiques, le modèle de sécurité Unix n'a plus de sens pour ce genre "d'utilisateur".

C'est là qu'Apache (le projet httpd) a pris deux décisions : une bonne et une mauvaise.

La bonne a consisté à modulariser le modèle d'exécution (appelé MPM pour "Multi Processing Module") afin de pouvoir explorer les options du futur et pouvoir facilement interchanger les modèles. Ceci a permis une compatibilité ascendante 100%, ainsi que la possibilité pour tous de tester de nouveaux modèles, encore une fois avec de simples "boutons on/off".

La mauvaise a consisté à parier sur les threads - contre l'avis de l'auteur du "C10K problem" -, probablement un biais lié alors à la domination de Java dans les projets de la fondation Apache et au même pari technologique qu'avait fait Sun pour son écosystème fort de café 10 ans auparavant.

On s'est alors retrouvé avec deux MPMs principaux :

  • Prefork : le MPM originel, le canal historique. C'est un cheval de trait, robuste, fiable, il fait exactement le boulot et ne vous laissera jamais tomber. Mais il est lourd, vous pouvez en général espérer aller jusqu'à quelques centaines de processus par serveur - donc requêtes simultanées - mais est-ce suffisant ? Au même moment (années 2000) le "contenu" explose (vidéos, images) bien plus vite que la progression des connections Internet : les requêtes sont longues... Quand vous avez acheté à prix d'or le plus gros serveur qui existe pour 20k€, que vous atteignez 500 connections simultanées pour réaliser que vous servez au mieux 60 utilisateurs simultanés (parce que leur navigateur a décidé d'établir 8 connections par site), vous avez un sacré problème technique et économique.

  • Worker : le nouveau MPM à base de threads : chaque unité de travail est nettement moins coûteuse à créer et maintenir, mais il y a peu d'isolation entre elles (en gros on les regroupe par paquets d'environ 64 à 256 par processus). Ceci permet à Apache de passer tranquillement un ordre de grandeur et de pouvoir parler de plusieurs milliers de connections simultanés. Mais dans ce manque d'isolation vient surtout un problème de synchronisation : pour qu'aucun effet étrange ou simple crash ne se produise, il faut que tout code qui s'exécute au sein d'Apache soit thread-safe. Or 1/ le logiciel conçu pour être thread-safe est alors rare et 2/ c'est difficile à écrire et maintenir.

C'est ce dernier point qui a bloqué Apache entre deux âges technologiques. En particulier PHP a mis du temps à être thread-safe, et quand bien même PHP embarque lui-même de nombreuses bibliothèques (GD, Imagemagick, Curl, etc) qui ne sont pas toujours thread-safe. Bref, adopter le MPM Worker est possible, mais il faut une bonne expertise pour savoir si c'est possible si vous embarquez du PHP, et aussi avouons-le un peu d'inconscience.

C'est pour cela qu'encore aujourd'hui toutes les distributions installent par défaut Apache avec le MPM prefork, anticipant le fait que vous allez lui embarquer PHP (dit mod_php), afin que vous ayez une expérience stable. Non scalable, mais stable.

Cassons du mythe

Et pourtant chez Bearstech on utilise le MPM Worker (avec des threads) et PHP depuis 2008. Nous l'avions alors benchmarké jusqu'à 8000 connections simultanées sans problème, avec des ressources modestes. Mais le mythe a perduré : "Apache c'est lent", "il faut lui mettre un Nginx devant", etc. Tant pis pour vous... La quantité de serveurs HTTP que nous avons exploité avec Apache (par centaines à chaque instant) sur plus de 15 ans chez Bearstech et qui ont juste marché est phénoménale. Nous sommes rompus aux tests de charge et nous n'avons pas encore trouvé d'Apache (bien configuré) qui constitue un goulet d'étranglement, même sur du matériel moderne et surdimensionné.

La solution est détaillée dans notre papier initial dont le lien est ci-dessus, nous n'allons donc pas le paraphraser. Mais nous pouvons ajouter qu'Apache a rattrapé son retard en "Public Relations", le troisième MPM en "betâ" depuis fort longtemps est enfin stable : il s'agit de Event qui implémente le modèle prôné par "C10k". De façon technique ceci ne révolutionne rien puisque un expert Apache n'a jamais souffert de problème de performance, mais désormais on ne peut plus dire que Apache a "une architecture du siècle passé".

La seule note triste c'est que les distributions GNU/Linux continuent à installer Apache en MPM prefork/vintage par défaut, mais un tel habitus repose sur ce mécanisme que ce serait difficile de leur reprocher : casser la compatibilité ascendente en changeant le MPM par défaut d'Apache pourrait provoquer un séisme mondial d'ampleur difficile à imaginer.

Trollons un peu

Chez Bearstech nous exploitons toutes sortes de serveur HTTP (Apache, Nginx, Haproxy, Varnish, Traefik, etc.). Nous avons une longue et large expérience pratique de ces technologies dans des situations de production, et du coup des avis assez tranchés.

Apache a vu mod_http2 intégré de façon stable dans sa 2.4.17 le 09/09/15. C'est arrivé dans Nginx 1.9.5 le 22/09/15 et à l'arrache (implémentation from scratch non testée, contre bibliothèque de référence testé chez Apache). Non seulement Apache est à la page, mais il le fait avec son habituelle robustesse et flegme : bouton on/off pour activer le module, c'est en production et ça ne fera jamais parler de lui.

Apache est très polyvalent. Ne vous y trompez pas en comparant ses modules avec ceux de Nginx : vous en trouverez à peu près le même nombre, mais ils n'ont pas la même portée. Chez Apache vous trouverez des modules génériques, orthogonaux et combinables (LDAP + DAV + Proxy + SSL : aucun problème); chez Nginx on trouve surtout des cas très spécifiques et bizarres (Pubcookie, Sorted Query String, Set lang, ...), et rarement composables entre eux. Nous l'affirmons car nous nous sommes plusieurs fois heurté à ces difficultés.

Enfin la syntaxe d'Apache avec ses portés explicites (global/vhost/directory) vous permet de comprendre et prévoir le comportement de la configuration, alors que la tentative de "C-like" de Nginx et très piégeuse, il n'y a pas de contextes hiérarchiques. Il y a d'ailleurs un fameux warning officiel sur une des directives principales qui tend à le faire croire : https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil (on confirme, le "if" ça mord).

Mais alors Nginx : bouuuuh ? Loin de là, on en exploite une bonne tribu en production car Nginx sait quand même fonctionner à un ordre de grandeur supérieur qu'Apache (50 000 connections simultanées sans problème) si on ne lui confie qu'une tâche à configuration simple et fixe comme servir des fichiers statiques ou faire le reverse proxy (et dans ce dernier cas il se fait botter le train d'un autre ordre de grandeur en performance et polyvalence par Haproxy). Mais ce n'est un qu'un cas d'usage parmi d'autre et Nginx n'est pas ce qu'on peut adapter de mieux à toutes les situations.

Conclusion

Avant de jeter vos "vieux" Apache ou de céder aux sirènes du marketing, demandez-vous si vous n'avez pas, peut être, un V8 surpuissant et incassable mais dont personne n'a pris la peine d'ouvrir le capot, voire d'enclencher la seconde. Bearstech peut vous aider pour vos problèmes de mécanique HTTP, appelez-nous.

Les ours aiment Apache

Service Hébergement et Infogérance apache

Bearstech vous propose ses services Hébergement et Infogérance apache

Découvrir ce service

Partager cet article

Flux RSS

flux rss

Partager cet article :

Nos expertises technologiques