ARCHITECTURE
WEB
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”
Internet
Internet 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
Quelques chiffres
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
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 ?
ETAPE                                 OUTILS                 PROBLEMES
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ù ?
                                                                Etape supplémentaire, puissance
Load balancing                     F5, Varnish, Ngnix, IIS
                                                                machine
Serveurs de cache                  F5, Varnish, Ngnix, IIS      Cache miss, puissance machine
                                                                Mauvaise configuration, puissance
Serveurs applicatifs               IIS, Apache, Rails, Java
                                                                machine
                                                                Requêtes lentes/inutiles, puissance
Base de données                    MySQL, PostGre, MSSQL
                                                                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 à
                                     Navigateur Web             Complexité de structure
partir du HTML
Chargement des images              Navigateur Web               Lourdeur/nombre des images
                                                                Complexité vs Puissance machine
Exécution du JavaScript            Navigateur Web
                                                                locale
Chargement des ressources                                       Attente des services avant
                                   Navigateur Web
externes                                                        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-end
Composants classiques d’une application web
Load Balancer



Front 1      Front 2      Front 3   ...


 Files        DB 1         DB 2     ...
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
Caches
S’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 n
INNER JOIN event e ON n.nid = e.nid
INNER JOIN event_timezones tz ON tz.timezone = e.timezone
INNER JOIN node_access na ON na.nid = n.nid
LEFT JOIN domain_access da ON n.nid = da.nid
LEFT 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;
Memcached
Cache 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_accel
erators

Tous ont à peu de choses près les mêmes
principes de fonctionnement
Sans caches d’opcodes

           charger le      scanner le                              créer un      executer le
Requête                                   parser le script                                     Résultats
          fichier .php       lexicon                               opcode          opcode




                                        Avec...
                                          OUI
                           opcode en                  charger le
                            cache ?                    opcode


                                NON

           charger le      scanner le                              créer un      executer le
Requête                                   parser le script                                     Résultats
          fichier .php       lexicon                               opcode          opcode




                                                             stocker le opcode
                                                                 en cache
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

        Port : 80

       VARNISH


       Port : 8080

        APACHE
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

On veut exclure du cache les pages /login,
   /search, /admin et quelques autres


               if (req.url ~ "^/login.php" ||
                     req.url ~ "^/search.php"
               ||
                     req.url ~ "^/admin(.*)" ||
                     req.url ~ "^/visitor(.*)"
               ||
                     req.url ~ "^/staff(.*)" ||
                   ) { return(pass);
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
                                     Suppression des cookies, sauf si on est
if ( !( req.url ~ ^/admin/) ) {
  unset req.http.Cookie;             sur /admin
}




   Suppression des
    cookies Google
          Analytics   // 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*", "");
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.
Menu : TTL = 1 jour


                                       Les ESI permettent de
                                       découper la
                                       page en précisant,
                                       pour chaque bloc la
                  Actu : TTL = 5 min   durée de vie du cache,
                                       qui, n’oublions pas,
                                       peut être nulle pour
                                       certains blocs
Contenu : TTL = 20 min




                 Page : TTL = 1 mois
Esi INCLUDE



php"/>   <esi:include src="/content.php"/>   <esi:inclu
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           */      }                                     }
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 Balancer



Front 1    Front 2    Front 3      ...
 Cache 1    Cache 2    Cache 3   Cache 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 ?
       Varnish
       Apache
        APC
        PHP
      Memcached
Cloud
Non, 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 !

Cours 1/3 "Architecture Web"

  • 1.
  • 2.
    moi :) Maxime Topolov(@mtopolov) CTO & Co-Fondateur de Adyax (@adyax) Dans le dev/archi/web depuis 1995 mtopolov@adyax.com
  • 4.
  • 5.
    Ce que vousn’allez pas apprendre avec moi
  • 6.
    Debugger un dimanchesoir, la config des caches sur fft.fr pendant la finale du Rolland Garros
  • 7.
    Ni comment expliquerà un client que 15 millions de pages vues ne passeront pas sur un serveur chez OVH
  • 8.
    Même pas commentcorriger le merdier laissé par le précédent architecte, “parti pour de nouveaux horizons”
  • 10.
    Internet Internet est lastructure 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
  • 11.
  • 12.
    Un architecte ? C’estpas 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
  • 13.
    Il y a2 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...
  • 14.
    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
  • 15.
  • 16.
    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
  • 17.
    Da Quizz Si votresite affiche un taux de disponibilité (dans la moyenne mondiale) de 97,8 % combien de temps est-il indisponible sur une année ?
  • 18.
    Da Quizz A :2,2 Jours B : 8 heures C : 8 jours D : 2200 secondes
  • 20.
    Et la bonneré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€
  • 21.
    Taux de disponibilité Secalcule 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é
  • 22.
    Temps de chargement 1seconde 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 !
  • 23.
    Couts cachés Détérioration del’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...
  • 24.
  • 25.
    France.fr Mauvaise architecture 3 moisde 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
  • 26.
  • 28.
    Quelques chiffres 29 millionsde 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
  • 29.
    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$
  • 30.
  • 31.
    Da Quizz Quels sontles étapes pour charger une page web depuis la saisie d’une URL dans le navigateur jusqu’à sont affichage complet ?
  • 33.
    ETAPE OUTILS PROBLEMES 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ù ? Etape supplémentaire, puissance Load balancing F5, Varnish, Ngnix, IIS machine Serveurs de cache F5, Varnish, Ngnix, IIS Cache miss, puissance machine Mauvaise configuration, puissance Serveurs applicatifs IIS, Apache, Rails, Java machine Requêtes lentes/inutiles, puissance Base de données MySQL, PostGre, MSSQL 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 à Navigateur Web Complexité de structure partir du HTML Chargement des images Navigateur Web Lourdeur/nombre des images Complexité vs Puissance machine Exécution du JavaScript Navigateur Web locale Chargement des ressources Attente des services avant Navigateur Web externes d'afficher
  • 34.
    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 * * * )
  • 35.
  • 36.
    Quelques chiffres Temps dechargement total de la page ? Nombre d’objets à charger (et donc de requêtes à faire) ? Poids total de la page ?
  • 38.
    Les «bonnes» réponses Temps de chargement : 7 secondes Nombre d’objets : 177 Poids total : 2,57 Mo
  • 40.
    Il y ade quoi faire...
  • 42.
    Front-End & Back-end Composantsclassiques d’une application web
  • 43.
    Load Balancer Front 1 Front 2 Front 3 ... Files DB 1 DB 2 ...
  • 44.
    Front-end Répond à larequê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...
  • 45.
    Back-end Base de donnéesla plupart du temps (MySQL, MongoDB, Oracle, MSSQL, etc...) Moteur de recherche (SOLR, Sphinx, ...)
  • 46.
  • 48.
    Load balancer Peut êtrematériel ou logiciel Attention au Single Point Of Failure Souvent les LB sont de la résponsabilité de l’hébergeur Difficiles à scaler
  • 49.
    Proxy Servent à lasécurité Trafic anonyme Logs de trafic Accélération (cache internet d’un sous réseau)
  • 50.
  • 51.
    Caches S’il y aun chapitre a suivre c’est celui-là
  • 53.
    Pourquoi cacher ? Eviterde 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++
  • 54.
    Quels caches ona : 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)
  • 55.
    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)
  • 56.
    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 n INNER JOIN event e ON n.nid = e.nid INNER JOIN event_timezones tz ON tz.timezone = e.timezone INNER JOIN node_access na ON na.nid = n.nid LEFT JOIN domain_access da ON n.nid = da.nid LEFT 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;
  • 58.
    Memcached Cache 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
  • 59.
    $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
  • 60.
    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
  • 61.
  • 62.
    Cache de laBDD 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
  • 63.
    Caches op-codes APC oueAccelerator, ou XCache, ou Zend Optimizer, ou ... http://en.wikipedia.org/wiki/List_of_PHP_accel erators Tous ont à peu de choses près les mêmes principes de fonctionnement
  • 64.
    Sans caches d’opcodes charger le scanner le créer un executer le Requête parser le script Résultats fichier .php lexicon opcode opcode Avec... OUI opcode en charger le cache ? opcode NON charger le scanner le créer un executer le Requête parser le script Résultats fichier .php lexicon opcode opcode stocker le opcode en cache
  • 65.
  • 66.
    Cache statique enfrontal Utilisé sur quasiment tous les sites web d’envergure Un outil open-source ressort : Varnish Si vous êtes riches : prenez un F5 (matériel)
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
    Installation classique Port : 80 VARNISH Port : 8080 APACHE
  • 72.
    Problèmes Certaines pages nepeuvent 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
  • 73.
    Exclusion de pages Unepage 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
  • 74.
    Exemple de confVCL On veut exclure du cache les pages /login, /search, /admin et quelques autres if (req.url ~ "^/login.php" || req.url ~ "^/search.php" || req.url ~ "^/admin(.*)" || req.url ~ "^/visitor(.*)" || req.url ~ "^/staff(.*)" || ) { return(pass);
  • 75.
    Cookies ATTENTION Varnish, commela 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.
  • 76.
    Config Varnish Cookies Suppression des cookies, sauf si on est if ( !( req.url ~ ^/admin/) ) { unset req.http.Cookie; sur /admin } Suppression des cookies Google Analytics // 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*", "");
  • 77.
    Cacher des morceaux Lanorme 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.
  • 79.
    Menu : TTL= 1 jour Les ESI permettent de découper la page en précisant, pour chaque bloc la Actu : TTL = 5 min durée de vie du cache, qui, n’oublions pas, peut être nulle pour certains blocs Contenu : TTL = 20 min Page : TTL = 1 mois
  • 80.
    Esi INCLUDE php"/> <esi:include src="/content.php"/> <esi:inclu
  • 81.
    ESI Include Il fautdonc 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
  • 82.
    Enfin, coté VCL subvcl_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 */ } }
  • 83.
    Duplication des caches Surles 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
  • 84.
    Load Balancer Front 1 Front 2 Front 3 ... Cache 1 Cache 2 Cache 3 Cache X
  • 85.
    Duplication de caches Lasolution peut-être la mise en place d’un Varnish au niveau du load-balancing Les caches sont alors communs à l’ensemble de l’application
  • 86.
    Limitations de caches Lecache 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
  • 87.
    Solution ? Optimiser lagé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.
  • 88.
    Exemple : Evene.fr Plusde 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
  • 89.
    Invalidation des pages Poserun 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...
  • 90.
    Invalidation varnish Reboot devarnish (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...
  • 91.
  • 92.
    Exemple d’un serveur front-end ? Varnish Apache APC PHP Memcached
  • 93.
    Cloud Non, je neferai pas de blagues pourries avec les nuages.
  • 95.
    Grands principes Virtualisation desserveurs (l’application est installée dans une enveloppe) Grosses machines très standardisées (sur lesquelles on met X serveurs virtuels)
  • 96.
    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é
  • 97.
    Myths breaker Un siteavec 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
  • 98.
    Exemple : Acquia Hostingsur le cloud de Amazon Uniquement de sites Drupal Mais en vrai ils ne sont pas très différents d’un hébergeur classique
  • 99.
  • 100.
    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,...
  • 101.
    La suite 2 Exempled'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
  • 102.
    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 ;-)
  • 103.
  • 104.