cours 1/3 "architecture web"

Post on 30-Nov-2014

6.895 Views

Category:

Technology

4 Downloads

Preview:

Click to see full reader

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...) Cloud

TRANSCRIPT

ARCHITECTURE WEB

Cours 1

moi :)

Maxime Topolov (@mtopolov)

CTO & Co-Fondateur de Adyax (@adyax)

Dans le dev/archi/web depuis 1995

mtopolov@adyax.com

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 : flemoing@adyax.com (un ex-HETICien)

Les stagiaires gèrent de vrai projets (cf. Pierre-Loïc ;-)

Des questions ?

Bye bye !

top related