cours 1/3 "architecture web"
DESCRIPTION
Cours de 1h30 pour HETIC - H4. Architecture Web. Présentation générale de l'architecture web, bons et mauvais exemples. Présentation des load balancers & proxys Présentation des caches (memcached, varnish...) CloudTRANSCRIPT
ARCHITECTURE WEB
Cours 1
moi :)
Maxime Topolov (@mtopolov)
CTO & Co-Fondateur de Adyax (@adyax)
Dans le dev/archi/web depuis 1995
VOUS ?
Ce que vous n’allez pas apprendre avec
moi
Debugger un dimanche soir, la config des caches sur fft.fr pendant la finale du Rolland
Garros
Ni comment expliquer à un client que 15 millions de pages vues ne passeront pas sur
un serveur chez OVH
Même pas comment corriger le merdier laissé par le précédent architecte, “parti pour
de nouveaux horizons”
InternetInternet est la structure technique sur laquelle est construit le WEB. Certains composants sont essentiels : DNS - permettant à un humain de trouver un site et le TCP - protocole permettant la communication entre un navigateur et un serveur
Architecture ?
Un architecte ?
C’est pas une star
Il n’est pas obligé de tout connaitre
Il est obligé d’en savoir un peu sur tout
Ce n’est pas un sys-admin
Il y a 2 manières de concevoir une application : soit de la manière la plus simple qu’il soit, il est alors évident qu’il n’y a pas d’anomalies, soit de la manière la plus complexe, il n’est alors pas évident de
trouver les anomalies. La première méthode est de loin la plus complexe...
Architecture web ?
Flux : qui parle à qui et en quelle langue ?
Soft : quels composants logiciels je vais utiliser et pourquoi ?
Hard : quels machines choisir pour quel usage ?
Combien : couts, nombre de machines, bande passante, jours-homme
Magic : optimisation, tunning & debug
Mauvaise architecture
Mauvaise architecture
Site lent = perte de revenu
Site tombe lors de pic de trafic = perte de revenu
Bugs aléatoires = charges d’audit et correctifs
Compensation hard = perte de marge
Da Quizz
Si votre site affiche un taux de disponibilité (dans la moyenne mondiale) de 97,8 % combien de temps est-il indisponible sur une année ?
Da Quizz
A : 2,2 Jours
B : 8 heures
C : 8 jours
D : 2200 secondes
Et la bonne réponse est
8 jours !
Donc, si votre site e-commerce fait 100K€ par jour (CA annuel de 36M€ = tous les sites e-commerce dans le top 25 France)...
Vous perdez 800.000 € par an...
Salaire d’un bon architecte web : 50K€
Taux de disponibilité
Se calcule en pourcentages
Varie entre 95% et 99,999%
365 jours x 24 heures x 3600 secondes = 31.536.000 secondes
Un taux de X% = X*31.536.000/100/3.600 heures d’indisponibilité
Temps de chargement
1 seconde de temps de chargement supplémentaire correspond à 7% de taux d’abandon
Avec notre site à 100K€ par jour cela correspond à 2,5M€ de pertes de CA par an !
Pas besoin d’avoir du gros trafic pour avoir un site lent !
Couts cachés
Détérioration de l’image de marque
Nombre d’appels plus importants au support
Couts de développements induits
Augmentation des couts (personnel, hard, bande passante, CDN...)
ROI des campagnes publicitaires en baisse
Impacts écologiques...
Exemple
France.fr
Mauvaise architecture
3 mois de site hors-ligne après le lancement
Image de la France écornée
Difficulté à placer Drupal sur plusieurs appels d’offres
Impacts se chiffrant en millions d’euros
Contre-exemple
29 millions de visiteurs uniques par mois
100 millions de pages vues par jour
8.000 recherches par seconde
Taux de disponibilité : 99,65 %
Temps d’affichage : 6 secondes
CA : 60.000.000 USD
Quelques chiffres
Comment faire 7M$ en 13 mois ?
Durée des travaux : 13 mois
Taux de disponibilité : 99,65% -> 99,97%
Temps de chargement : 6 sec -> 1,2 sec
Chiffre d’affaires : +12% = +7,2M$
Architecture web ?
Da Quizz
Quels sont les étapes pour charger une page web depuis la saisie d’une URL dans le navigateur jusqu’à sont affichage complet ?
ETAPEETAPE OUTILSOUTILS PROBLEMESPROBLEMES
Etablissement d'une connexion TCP Navigateur Web Négociation TCP
Envoi de la requête vers l'opérateur Box / DSLAM Routage
Récupération de l'adresse IP DNS Problèmes DNS
Routage vers les serveurs Switchs La chine ? C'est où ?
Load balancing F5, Varnish, Ngnix, IIS Etape supplémentaire, puissance machine
Serveurs de cache F5, Varnish, Ngnix, IIS Cache miss, puissance machine
Serveurs applicatifs IIS, Apache, Rails, Java Mauvaise configuration, puissance machine
Base de données MySQL, PostGre, MSSQL Requêtes lentes/inutiles, puissance machine
Construction de la page HTML Drupal, RoR, ASP.NET, PHP… Lourdeur du CMS/Framework
Compression de la page gZip :) …
Envoi du flux par paquets TCP IIS, Apache, Rails, Java Lourdeur des pages
Routage Switchs …
Génération visuelle de du résultat à partir du HTML Navigateur Web Complexité de structure
Chargement des images Navigateur Web Lourdeur/nombre des images
Exécution du JavaScript Navigateur Web Complexité vs Puissance machine locale
Chargement des ressources externes Navigateur Web Attente des services avant d'afficher
traceroute
traceroute to www.google.com (173.194.34.18), 64 hops max, 52 byte packets 1 85-171-156-1.rev.numericable.fr (85.171.156.1) 24.643 ms 17.714 ms 13.625 ms 2 * * * 3 ip-185.net-80-236-8.asnieres.rev.numericable.fr (80.236.8.185) 17.179 ms 21.223 ms 9.897 ms 4 172.19.128.170 (172.19.128.170) 17.496 ms 15.597 ms 21.259 ms 5 ip-161.net-80-236-1.static.numericable.fr (80.236.1.161) 14.616 ms 16.182 ms 61.046 ms 6 72.14.239.145 (72.14.239.145) 25.932 ms 19.269 ms 12.210 ms 7 209.85.242.45 (209.85.242.45) 14.380 ms 26.051 ms 25.651 ms 8 par03s02-in-f18.1e100.net (173.194.34.18) 15.521 ms 22.093 ms 21.382 ms
8 étapes pour arriver chez Google
Jusqu’à 200ms pour certains paquets
Problèmes réseau avec ma box (2 * * * )
Da Quizz Hetic !
Quelques chiffres
Temps de chargement total de la page ?
Nombre d’objets à charger (et donc de requêtes à faire) ?
Poids total de la page ?
Les «bonnes» réponses
Temps de chargement : 7 secondes
Nombre d’objets : 177
Poids total : 2,57 Mo
Il y a de quoi faire...
Front-End & Back-endComposants classiques d’une application
web
Load BalancerLoad Balancer
Front 1Front 1 Front 2Front 2 Front 3Front 3 ......
DB 1DB 1 DB 2DB 2FilesFiles ......
Front-end
Répond à la requête de l’utilisateur = génère le HTML, XML, JSON, ... demandé
Serveur Web : Apache, IIS, NGnix, Lighthttpd, Puma, Thin
Cache statique : Varnish, Memcached
Code de l’application : PHP, RoR, Java, Python...
Back-end
Base de données la plupart du temps (MySQL, MongoDB, Oracle, MSSQL, etc...)
Moteur de recherche (SOLR, Sphinx, ...)
Load balancers & Proxys
Load balancer
Peut être matériel ou logiciel
Attention au Single Point Of Failure
Souvent les LB sont de la résponsabilité de l’hébergeur
Difficiles à scaler
Proxy
Servent à la sécurité
Trafic anonyme
Logs de trafic
Accélération (cache internet d’un sous réseau)
Pour résumer
CachesS’il y a un chapitre a suivre c’est celui-là
Pourquoi cacher ?
Eviter de refaire un travail déjà effectué
Pour aller vite
Parce que la RAM ne coute pas cher
Parce que on ne code pas de sites en C++
Quels caches on a :
Dans les équipements réseau (DNS, Routeurs)
Interne à une application (Memcached, Redis)
Au niveau de la base de données
Au niveau des scripts PHP (APC, eAccelerator)
Devant un serveur web (Varnish, Apache)
Cache interne à l’application
On cache un résultat intermédiaire lors de la génération d’une page (liste des commentaires)
On cache ce qui peut être commun à plusieurs pages (menu principal)
On cache pour ne pas stocker en base (sessions des utilisateurs)
SELECT DISTINCT n.nid, n.uid, n.title, n.type, e.event_start, e.event_start AS event_start_orig, e.event_end, e.event_end AS event_end_orig, e.timezone, e.has_time, e.has_end_date, tz.offset AS offset, tz.offset_dst AS offset_dst, tz.dst_region, tz.is_dst, e.event_start - INTERVAL IF(tz.is_dst, tz.offset_dst, tz.offset) HOUR_SECOND AS event_start_utc, e.event_end - INTERVAL IF(tz.is_dst, tz.offset_dst, tz.offset) HOUR_SECOND AS event_end_utc, e.event_start - INTERVAL IF(tz.is_dst, tz.offset_dst, tz.offset) HOUR_SECOND + INTERVAL 0 SECOND AS event_start_user, e.event_end - INTERVAL IF(tz.is_dst, tz.offset_dst, tz.offset) HOUR_SECOND + INTERVAL 0 SECOND AS event_end_user, e.event_start - INTERVAL IF(tz.is_dst, tz.offset_dst, tz.offset) HOUR_SECOND + INTERVAL 0 SECOND AS event_start_site, e.event_end - INTERVAL IF(tz.is_dst, tz.offset_dst, tz.offset) HOUR_SECOND + INTERVAL 0 SECOND AS event_end_site, tz.name as timezone_name FROM node nINNER JOIN event e ON n.nid = e.nidINNER JOIN event_timezones tz ON tz.timezone = e.timezoneINNER JOIN node_access na ON na.nid = n.nidLEFT JOIN domain_access da ON n.nid = da.nidLEFT JOIN node i18n ON n.tnid > 0 AND n.tnid = i18n.tnid AND i18n.language = 'en'WHERE (na.grant_view >= 1 AND ((na.gid = 0 AND na.realm = 'all'))) AND ((da.realm = "domain_id" AND da.gid = 4) OR (da.realm = "domain_site" AND da.gid = 0)) AND (n.language ='en' OR n.language ='' OR n.language IS NULL OR n.language = 'is' AND i18n.nid IS NULL) AND ( n.status = 1 AND ((e.event_start >= '2010-01-31 00:00:00' AND e.event_start <= '2010-03-01 23:59:59') OR (e.event_end >= '2010-01-31 00:00:00' AND e.event_end <= '2010-03-01 23:59:59') OR (e.event_start <= '2010-01-31 00:00:00' AND e.event_end >= '2010-03-01 23:59:59')) )GROUP BY n.nid HAVING (event_start >= '2010-02-01 00:00:00' AND event_start <= '2010-02-28 23:59:59') OR (event_end >= '2010-02-01 00:00:00' AND event_end <= '2010-02-28 23:59:59') OR (event_start <= '2010-02-01 00:00:00' AND event_end >= '2010-02-28 23:59:59')ORDER BY event_start ASC;
MemcachedCache mémoire clé-valeur, en cluster (!)
Très rapide, très simple à utiliser
Mémoire = si memcached tombe, vous perdez tout, donc on y met rien d’important
Intégré à la plupart des CMS (Drupal, Magento) ou des Frameworks
$huge_data_for_front_page = $memcache->get("huge_data_for_front_page");if($huge_data_for_front_page === false){ $huge_data_for_front_page = array(); $sql = "SELECT * FROM hugetable WHERE timestamp > lastweek ORDER BY timestamp ASC LIMIT 50000"; $res = mysql_query($sql, $mysql_connection); while($rec = mysql_fetch_assoc($res)){ $huge_data_for_frong_page[] = $rec; } // cache for 10 minutes $memcache->set("huge_data_for_front_page", $huge_data_for_front_page, 0, 600);}
// use $huge_data_for_front_page how you please
Le principe reste le même, quelque soit l’application qui utiliserait memcached : on
regarde, si pour une clé X, on a de la donnée, si oui, on continue, si non on va chercher sur le
back-end et on enregistre dans memcached pour Y temps
Que met-on dans memcached
Résultat de requêtes longues
Résultat d’appels aux web-services
Sessions des utilisateurs
Objets jetables à partager entre des serveurs front
QR-Memcached
Cache de la BDD
Indexes, ne sont que des caches clé-valeur
Les données d’une base sont stockés sur les disques = IO lents
Plus on alloue de RAM à un serveur BDD mieux c’est
Attention, si votre base est utilisée en écriture, activer le cache sera pénalisant
Caches op-codes
APC ou eAccelerator, ou XCache, ou Zend Optimizer, ou ...
http://en.wikipedia.org/wiki/List_of_PHP_accelerators
Tous ont à peu de choses près les mêmes principes de fonctionnement
RequêteRequête charger le charger le fichier .phpfichier .php
scanner le scanner le lexiconlexicon
parser le parser le scriptscript
créer un créer un opcodeopcode
executer le executer le opcodeopcode RésultatsRésultats
RequêteRequête charger le charger le fichier .phpfichier .php
scanner le scanner le lexiconlexicon
parser le parser le scriptscript
créer un créer un opcodeopcode
executer le executer le opcodeopcode RésultatsRésultats
opcode opcode en en
cache ?cache ?
charger le charger le opcodeopcode
stocker le stocker le opcode en opcode en
cachecache
OUI
NON
Sans caches d’opcodes
Avec...
QR-APC
Cache statique en frontal
Utilisé sur quasiment tous les sites web d’envergure
Un outil open-source ressort : Varnish
Si vous êtes riches : prenez un F5 (matériel)
Sans cache, ca crache
Avec du cache
Avant - Après
Varnish c’est facile
Installation classique
APACHEAPACHE
Port : 8080Port : 8080
VARNISHVARNISH
Port : 80Port : 80
Problèmes
Certaines pages ne peuvent pas être cachées
Comment cacher un site complètement dynamique (twitter, facebook...) ?
Varnish, tout comme memcached est un cache chaud (on reboot = on perd tout)
Comment cacher des “morceaux” de pages
Comment invalider les caches
Duplication des caches
Exclusion de pages
Une page ne doit pas être cachée, si son contenu est lié à la session de l’utilisateur
Ce sont les pages mon compte, mon panier, pages de paiement
Pages HTTPS
Exemple de conf VCL
if (req.url ~ "^/login\.php" || req.url ~ "^/search\.php" || req.url ~ "^/admin(.*)" || req.url ~ "^/visitor(.*)" || req.url ~ "^/staff(.*)" || ) { return(pass);
if (req.url ~ "^/login\.php" || req.url ~ "^/search\.php" || req.url ~ "^/admin(.*)" || req.url ~ "^/visitor(.*)" || req.url ~ "^/staff(.*)" || ) { return(pass);
On veut exclure du cache les pages /login, /search, /admin et quelques autres
Cookies
ATTENTION Varnish, comme la plupart des caches, va passer au back-end toute requête HTTP avec un Cookie
Or, beaucoup de CMS, comme Drupal, posent des cookies, même pour les anonymes.
Config Varnish Cookies
if ( !( req.url ~ ^/admin/) ) { unset req.http.Cookie;}
Suppression des cookies, sauf si on est sur /admin
// Remove has_js and Google Analytics __* cookies.set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js)=[^;]*", "");// Remove a ";" prefix, if present.set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
Suppression des cookies Google
Analytics
Cacher des morceaux
La norme ESI (Edge Side Includes) permet de créer des caches complexes
ESI est en partie supporté par Varnish, mais aussi des F5 ou des CDN comme Akamai
ESI requiert du développement coté application.
Page : TTL = 1 mois
Actu : TTL = 5 min
Contenu : TTL = 20 min
Menu : TTL = 1 jour
Les ESI permettent de découper lapage en précisant, pour chaque bloc la durée de vie du cache, qui, n’oublions pas, peut être nulle pour certains blocs
Esi INCLUDE
<html> <body> <esi:include src="/menu.php"/> <esi:include src="/content.php"/> <esi:include src="/right-side-bar.php"/> <esi:include src="/footer.php"/> </body></html>
ESI Include
Il faut donc découper dans votre application la page en blocs indépendants (très simple avec les CMS/Frameworks actuels)
L’application décrit à Varnish, au niveau de chaque URL, comment construire la page
Enfin, coté VCL
sub vcl_fetch { if (req.url == "/main.php") { set beresp.do_esi = true; /* Lancons le process ESI */ set beresp.ttl = 720h; /* Pose le TTL à 30 jours */ } elseif (req.url == "/menu.php") { set beresp.ttl = 24h; /* 24h pour le menu */ } elseif (req.url == "/content.php") { set beresp.ttl = 20m; /* 20 minutes pour le contenu */ } elseif (req.url == "/right-side-bar.php") { set beresp.ttl = 1h; /* 1h pour la colonne de droite */ } elseif (req.url == "/footer.php") { set beresp.ttl = 24h; /* 24h pour le footer */ } }
sub vcl_fetch { if (req.url == "/main.php") { set beresp.do_esi = true; /* Lancons le process ESI */ set beresp.ttl = 720h; /* Pose le TTL à 30 jours */ } elseif (req.url == "/menu.php") { set beresp.ttl = 24h; /* 24h pour le menu */ } elseif (req.url == "/content.php") { set beresp.ttl = 20m; /* 20 minutes pour le contenu */ } elseif (req.url == "/right-side-bar.php") { set beresp.ttl = 1h; /* 1h pour la colonne de droite */ } elseif (req.url == "/footer.php") { set beresp.ttl = 24h; /* 24h pour le footer */ } }
Duplication des caches
Sur les sites à très fort trafics on va mettre en place plusieurs front avec un load balancer en face
Si chaque front embarque un varnish, le cache sera reconstruit et invalidé indépendamment sur chaque front
Load BalancerLoad Balancer
Front 1Front 1 Front 2Front 2 Front 3Front 3 ......
Cache 1Cache 1 Cache 2Cache 2 Cache 3Cache 3 Cache XCache X
Duplication de caches
La solution peut-être la mise en place d’un Varnish au niveau du load-balancing
Les caches sont alors communs à l’ensemble de l’application
Limitations de caches
Le cache est efficace quand beaucoup de monde demande la même ressource
Si j’ai 1.000.000 de pages avec un trafic également réparti entre les pages (annuaires, base de données documentaires, site avec un fort SEO en long trail) avec un taux de 1 hit par jour et par page, le cache ne sert à rien
Solution ?
Optimiser la génération des pages avec du NoSQL (MongoDB, par exemple) -> on a plus besoin de caches
TTL infini, avec un système d’invalidation très intelligent -> il faut être capable de savoir quand *chaque* page est invalidée
Crawling -> on simule un trafic permanent sur le site, on garde le cache au chaud.
Exemple : Evene.fr
Plus de 3.000.000 de pages
Architecture basée sur NGnix & Varnish
Un crawler qui passe en permanence sur toutes les pages
Google tape toujours dans des pages cachées = bon pour le SEO
Invalidation des pages
Poser un TTL ne suffit pas, on veut pouvoir rafraichir une page modifiée, avant l’expiration du cache
L’invalidation des pages de contenu est facile
Quid de l’invalidation des listes, résultats de recherche, etc...
Invalidation varnish
Reboot de varnish (extrème)
varnishadm - il faut un accès au terminal, mais on peut invalider en masse
purge HTTP par wget / curl - on fait page par page...
QR-Varnish
Exemple d’un serveur front-end ?
VarnishVarnish
MemcachedMemcached
ApacheApache
APCAPC
PHPPHP
CloudNon, je ne ferai pas de blagues pourries
avec les nuages.
Grands principes
Virtualisation des serveurs (l’application est installée dans une enveloppe)
Grosses machines très standardisées (sur lesquelles on met X serveurs virtuels)
Avantages
Hard standard -> coûts réduits
On optimise très bien le hard -> coûts réduits
Sauvegarde et disaster recovery simplifiés
Scalabilité simplifié
Myths breaker
Un site avec un fort trafic n’ira pas plus vite sur le cloud
L’intérêt du cloud = plein de petites applications
Mettre un site sur le cloud nécessite de la réflexion et du développement
Exemple : Acquia
Hosting sur le cloud de Amazon
Uniquement de sites Drupal
Mais en vrai ils ne sont pas très différents d’un hébergeur classique
Acquia Managed Cloud
La suite
Serveurs web : possibilités, NGnix, Apache, Lighthttpd, optimisations possibles
Applications : PHP, Java, .NET, Ruby
Bases de données : MySQL, NoSQL, avantages et inconvénients, requêtes lentes, tuning
Moteurs de recherche : Apache SOLR, Sphinx, MySQL Full text search, Antidot, Exalead
CDN : Videos, images, l'intérêt, Akamaï, CDN Tech,...
La suite 2
Exemple d'architecture appliqué à un CMS : Drupal
Exemple d'optimisations sur un site concret : Evene.fr, Bouygues-Immobilier.com
Sizing : comment construire une architecture
Test de performance, monitoring & supervision : JMeter, New Relic, Nagios
STAGES CHEZ ADYAX
C’est super cool (mieux que chez Publicis, TBWA ou Fullsix !)
On a un bar à 3 mètres avec des pintes à 4€
On a publié les offres sur l’OGI
Si non : [email protected] (un ex-HETICien)
Les stagiaires gèrent de vrai projets (cf. Pierre-Loïc ;-)
Des questions ?
Bye bye !