Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Varnish, ESI & Cookies @Service-Public

Varnish, ESI & Cookies @Service-Public

Cette présentation offre un retour d'expérience sur la refonte de service-public.fr. Varnish y a bien-sûr été utilisé comme moteur de cache pour des raisons de performance mais pas seulement. Il a aussi permis l'intégration en marque blanche des contenus d'un CMS grâce aux balises ESI, occasionnant quelques sueurs froides concernant notamment la gestion des cookies. Étant une première expérience sur Varnish, quelques tips vous seront partagés pour bien débuter.

Meetup : http://www.meetup.com/fr-FR/Paris-Varnish-Cache-Meetup/events/231121017/

Avatar for Benjamin BRABANT

Benjamin BRABANT

June 07, 2016

Other Decks in Programming

Transcript

  1. 50 AVENUE DES CHAMPS-ÉLYSÉES 75008 PARIS > FRANCE > WWW.OCTO.COM

    OXALIDE - 07/06/2016 VARNISH, ESI & COOKIES @SERVICE-PUBLIC Varnish Meetup
  2. SUJETS (DRAFT) ¤  Présenter les ESI >  Intégration Tier > 

    Politique de cache diversifié dans une page (TTL / Vary) ¤  Approche naïve >  Fail cookie perdu dans les sous-requêtes ESI Varnish ¤  Approche redirection navigateur >  Fail Robot Google >  Fail cookie désactivés (infini redirect) ¤  Approche redirection interne varnish >  Restart Varnish >  Fail parenté requête => req_top Varnish 4.1 >  Fail double Set-Cookie => libvmod header ¤  Varnish 3 : Module esicookies ¤  REX « Fourre-tout » >  ESI & Gestion d’erreurs >  Découpage VCL pour Varnish Test >  Système d’éviction du cache (PURGE vs BAN) >  Hit for Pass >  Default VCL ou Copier Coller Default VCL >  Outils : Varnishlog + Varnish Query Language + VarnishADM = <3 OCTO TECHNOLOGY > THERE IS A BETTER WAY 2
  3. OCTO TECHNOLOGY > THERE IS A BETTER WAY 3 VOUS

    CROYEZ QUE LES TECHNOLOGIES CHANGENT LE MONDE ? NOUS AUSSI ! REJOIGNEZ-NOUS ! [email protected]
  4. ARCHITECTURE TECHNIQUE OCTO TECHNOLOGY > THERE IS A BETTER WAY

    8 APP ADMIN JAVA UTILISATEUR DILA RÉDIGEANT LE CONTENU INTERNAUTES ADMINISTRATEURS TECHNIQUES DILA COPERIA ITM MOTEUR DE RECHERCHE AKIO SMPT VARNISH APP JAVA HTTPD VARNISH APP JAVA PAS DE REDONDANCE DB DB REDONDÉE CMS EZ HTTPD LOGSTASH LE VARNISH JOUE LE RÔLE DE LOAD BALANCER ET GARANTIT LE SLA DU CMS EZPUBLISH LOADBALANCER
  5. EDGE SIDE INCLUDE (ESI) ¤  ESI 1.0 ó Assemblage de

    fragments HTML à travers une syntaxe XML ¤  Principaux Intérêts : >  Politique de cache diversifiée dans une page (TTL / Vary) >  Intégration de contenus externe OCTO TECHNOLOGY > THERE IS A BETTER WAY 10 ESI + + =
  6. EDGE SIDE INCLUDE (ESI) OCTO TECHNOLOGY > THERE IS A

    BETTER WAY 11 <html xmlns:esi="..."> <head> <title>Hello World!</title> <meta name="description" value="Hello World!" /> </head> <body> <esi:include src="/hello/world" /> </body> </html> <!– Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris sed mauris lacus. Sed in efficitur orci. Sed id orci venenatis, cursus orci et, placerat diam. Sed non tristique ligula. Nunc maximus velit et felis auctor, sit amet semper purus ultricies. In imperdiet ac erat a semper. Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed sed odio ultrices, tristique augue ac, sollicitudin metus. --!>
  7. EDGE SIDE INCLUDE (ESI) ¤  Approche “Layout First” : > 

    Servir le squelette principal (non cacheable) à la première requête >  Appeler le contenu central en ESI (cacheable ou non) >  Aller chercher les blocs cacheables de la page en ESI également OCTO TECHNOLOGY > THERE IS A BETTER WAY 12 <html xmlns:esi="..."> <head> <meta name="_csrf" value="${_csrf.token}" /> </head> <body> <header>Lorem Ipsum</header> <esi:include src="/esi/content?uri=/ request" /> <footer>Lorem Ipsum</footer> </body> </html> <!-- here is the main content --!> layout.html content.html HEADER FOOTER CONTENT ESI
  8. EDGE SIDE INCLUDE (ESI) ¤  Approche “Content First” : > 

    Servir le contenu principal (cacheable ou non) à la première requête >  Aller chercher les blocs du squelette (cacheable ou non) en ESI OCTO TECHNOLOGY > THERE IS A BETTER WAY 13 <html xmlns:esi="..."> <head> <esi:include src="/esi/head" /> </head> <body> <esi:include src="/esi/header" /> <!-- here is the main content --!> <esi:include src="/esi/footer" /> </body> </html> <meta name="_csrf" value="${_csrf.token}"/> layout.html head.html CONTENT HEADER ESI FOOTER ESI
  9. VARNISH VS ESIGATE ¤ CACHING REVERSE PROXY ¤ ECRIT EN C ¤ SUPPORT

    ESI MINIMAL ¤ CUSTOMISATION PAR DSL VARNISH VCL OCTO TECHNOLOGY > THERE IS A BETTER WAY 14 ¤  IMPLÉMENTATION ESI COMPLÈTE ¤  ECRIT EN JAVA ¤  SUPPORT CACHING REVERSE PROXY ¤  GESTION DES COOKIES / ERREURS ¤  CUSTOMISATION PAR PROPERTIES
  10. VARNISH VS ESIGATE OCTO TECHNOLOGY > THERE IS A BETTER

    WAY 15 FEATURE (ESI 1.0) ESIGATE VARNISH <esi:include src="/url" alt="/url-alt" onerror=”continue|display" /> (src only) <esi:remove> <a href="http://www.example.com">www.example.com</a> </esi:remove> <!--esi <p>Edge Side Include supported</p> --> <esi:comment text="the following animation will have a 24 hr TTL." /> <esi:try> <esi:attempt>...</esi:attempt> <esi:except code="404">...</esi:except> <esi:except code="500">...</esi:except> <esi:except>...</esi:except> </esi:try> <esi:choose> <esi:when test="..."> ... </esi:when> <esi:when test="..."> ... </esi:when> <esi:otherwise> ... </esi:otherwise> </esi:choose> <esi:vars> <img src="http://www.example.com/$(HTTP_COOKIE{type})/hello.gif"/ > </esi:vars> <esi:inline name="URI" fetchable="{yes | no}”> fragment to be stored within an ESI processor </esi:inline>
  11. POURQUOI AVOIR CHOISI VARNISH ? OCTO TECHNOLOGY > THERE IS

    A BETTER WAY 16 VARNISH + ESIGATE è VOLONTÉ DE SIMPLIFIER L’ARCHITECTURE ü ü ü ü VARNISH DÉJÀ UTILISÉ POUR LE CACHE EZPUBLISH VARNISH SOLUTION RECONNUE DANS LE DOMAINE DU CACHE APPLICATIF PAS DE PARTIE AUTHENTIFIÉE À L’ÉPOQUE DU CHOIX
  12. RAPPEL : VARNISH 4 FLOW HOOKS DANS LE CYCLE DE

    VIE DE LA REQUÊTE OCTO TECHNOLOGY > THERE IS A BETTER WAY 18 ¤  vcl_recv : requête client reçue ¤  vcl_hash : calcul clé de hash ¤  vcl_hit : objet trouvé en cache ¤  vcl_miss : objet non en cache ¤  vcl_backend_fetch : requête au serveur ¤  vcl_backend_response : réponse du serveur ¤  vcl_deliver : prêt à répondre au client
  13. CAS PRATIQUE : SERVICE-PUBLIC.FR OCTO TECHNOLOGY > THERE IS A

    BETTER WAY 20 <!DOCTYPE html> <html xmlns:esi="http://www.edge-delivery.org/esi/1.0" lang="fr"> <head> <title>Vos Questions - Service Public</title> <meta name="description" content="Le site officiel de l'administration française - Service Public"> <esi:include src="/esi/head?esiTargetUrl=/vos-questions" /> </head> <body> <header class="banner" role="banner"> <esi:include src="/esi/header?esiTargetUrl=/vos-questions" /> </header> <esi:include src="/esi/search" /> <main class="main" id="main" role="main"> <div class="container main-container"> Lorem ipsum dolor sit amet, consectetur adipiscing elit. </div> </main> <footer class="footer" role="contentinfo"> <esi:include src="/esi/footer" /> </footer> <esi:include src="/esi/javascripts" /> <esi:include src="/esi/marquage" /> </body> </html>
  14. CAS PRATIQUE : SERVICE-PUBLIC.FR ¤  BANDEAU DE LOGIN SERVI PAR

    FRAGMENT ESI ¤  CONTENU PRINCIPAL POTENTIELLEMENT EN CACHE ¤  TOKEN CSRF ASSOCIÉ AU FORMULAIRE REGÉNÉRÉ À CHAQUE CHARGEMENT è PAS DE CACHE ¤  TOKEN CSRF LIÉ AU COOKIE DE SESSION UTILISATEUR ARRIVANT LA PREMIÈRE FOIS SANS COOKIE DE SESSION SE RETROUVENT AVEC UN TOKEN CSRF INVALIDE è POURQUOI ? OCTO TECHNOLOGY > THERE IS A BETTER WAY 21
  15. PROBLÈME : PERTE DU COOKIE OCTO TECHNOLOGY > THERE IS

    A BETTER WAY 22 SQUELETTE EN CACHE FRAGMENT NO CACHE CLIENT VARNISH BACKEND UTILISATEUR SANS COOKIE INITIALEMENT, L’APPEL AU BACKEND POUR LE FRAGMENT GÉNÈRE UN COOKIE LA RÉPONSE FINALE NE CONTIENT PLUS DE COOKIE GET /hello ESI /header 200 /hello HIT /hello
  16. PROBLÈME [RÉCAPITULATIF] OCTO TECHNOLOGY > THERE IS A BETTER WAY

    23 ¤  Première visite de l’utilisateur ó Pas de Cookie Session ¤  Fragment principal potentiellement en cache ¤  Génération Cookie Session par le fragment header (no-cache) ¤  Header Set-Cookie non remonté dans la réponse principale è Token CSRF invalide sans Cookie Session
  17. SOLUTION « REDIRECTION NAVIGATEUR » : PERTE D’UTILISATEURS OCTO TECHNOLOGY

    > THERE IS A BETTER WAY 24 SQUELETTE EN CACHE FRAGMENT NO CACHE CLIENT VARNISH BACKEND UTILISATEUR SANS COOKIE INITIALEMENT, APPEL D’UN ENDPOINT DE GÉNÉRATION DU COOKIE DE SESSION, REDIRECTION DU NAVIGATEUR VERS LA PAGE INITIALE AVEC COOKIE DE SESSION LA DÉSACTIVATION DES COOKIES ENTRAINE UNE REDIRECTION INFINIE (ROBOT INDEXATION, …) GET /hello 200 /hello GET /session?redirect=/hello 302 /hello GET /hello HIT /hello ESI /header
  18. SOLUTION « REDIRECTION NAVIGATEUR » [RÉCAPITULATIF] OCTO TECHNOLOGY > THERE

    IS A BETTER WAY 25 ¤  Endpoint /session : Créer/Rafraîchir Cookie Session utilisateur ¤  Appel du endpoint de génération de session si nécessaire au préalable de chaque requête GET ¤  Renvoie d’une redirection 302 vers la page initiale avec nouveau Cookie de Session ¤  Requête initiale avec cette fois un Cookie de Session è Problèmes : Robots indexeurs ne supportant pas les cookies & Boucle de redirection si cookies navigateur désactivés
  19. SOLUTION « RESTART INTERNE VARNISH » OCTO TECHNOLOGY > THERE

    IS A BETTER WAY 26 SQUELETTE EN CACHE FRAGMENT NO CACHE CLIENT VARNISH BACKEND UTILISATEUR SANS COOKIE INITIALEMENT, APPEL D’UN ENDPOINT DE GÉNÉRATION DU COOKIE DE SESSION, VARNISH RESTART SUR LA PAGE INITIALE EN INJECTANT LE COOKIE DE SESSION RÉPONSE COHÉRENTE AVEC UN « SET-COOKIE » DE SESSION GET /hello 200 /hello GET /session?redirect=/hello RESTART /hello HIT /hello ESI /header Varnish forge les sous-requêtes ESI à partir de la requête originelle è Passage du cookie de session aux sous- requêtes ESI via la variable req_top (Varnish 4.1+)
  20. LIMITATION AVEC VARNISH 4 ¤  Au moment du vcl_deliver du

    fragment principal, Varnish lance un restart (retour dans vcl_recv) pour chaque fragment ESI à récupérer ¤  Impossible de passer à la requête principale un élément provenant de la réponse d’un fragment ESI ¤  Un VMOD esicookies existe seulement pour Varnish 3 https://code.uplex.de/uplex-varnish/libvmod-esicookies OCTO TECHNOLOGY > THERE IS A BETTER WAY 27
  21. SOLUTION « RESTART INTERNE VARNISH » [RÉCAPITULATIF] OCTO TECHNOLOGY >

    THERE IS A BETTER WAY 28 ¤  Endpoint /session : Créer/Rafraîchir Cookie Session utilisateur ¤  Appel du endpoint systématique à chaque requête GET ¤  Renvoie nouveau Cookie de Session si nécessaire ¤  Varnish restart la requête initiale avec le Cookie de session ¤  Passage du Cookie de Session aux sous-requêtes ESI via la variable req_top (Varnish 4.1 only) è  Cookie Session systématique pour chaque utilisateur è  Token CSRF consistant dans la page
  22. VCL_RECV OCTO TECHNOLOGY > THERE IS A BETTER WAY sub

    vcl_recv { if (req.restarts == 0) { if (req.http.X-Forwarded-For) { # set or append the client.ip to X-Forwarded-For header set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; } else { set req.http.X-Forwarded-For = client.ip; } } # Dans un fragment ESI, on récupère le cookie de la requête parente if (req.esi_level > 0) { set req.http.Cookie = req_top.http.X-Cookies; } call sp_purge; call sp_ban; call sp_healthcheck; if (! std.healthy(apps.backend())) { return(synth(503, {""})); } call sp_choose_backend; call sp_clean_request; call sp_session_generate; # return (hash); }
  23. SP_CLEAN_REQUEST OCTO TECHNOLOGY > THERE IS A BETTER WAY sub

    sp_clean_request { call sp_clean_request_host; call sp_clean_request_url; if (req.http.Cookie) { # Handle SPPlus webapp cookie. Store it temporarily set req.http.X-Cookies = ";" + req.http.Cookie; set req.http.X-Cookies = regsuball(req.http.X-Cookies, "; +", ";"); set req.http.X-Cookies = regsuball(req.http.X-Cookies, ";(SPREMEMBER|SPPLUS_SESSION)=", "; \1="); set req.http.X-Cookies = regsuball(req.http.X-Cookies, ";[^ ][^;]*", ""); set req.http.X-Cookies = regsuball(req.http.X-Cookies, "^[; ]+|[; ]+$", ""); # Clean empty webapp cookie if (req.http.X-Cookies ~ "^ *$") { unset req.http.X-Cookies; } # Remove all others cookies unset req.http.Cookie; } }
  24. SP_SESSION_GENERATE OCTO TECHNOLOGY > THERE IS A BETTER WAY sub

    sp_session_generate { if (req.restarts == 0 && req.esi_level == 0 && (req.method == "GET" || req.method == "HEAD")) { # Préparation de l'URL de redirection ## Encodage URL des '&' set req.url = regsuball(req.url, "&", "%26"); # Construction de la requête de construction de session set req.url = "/session" + "?redirect=" + req.url; # Sélection du backend pour le endpoint de génération de session call sp_choose_backend; return (pass); } }
  25. VCL_DELIVER [SESSION RESPONSE] OCTO TECHNOLOGY > THERE IS A BETTER

    WAY sub vcl_deliver { if (req.http.X-Cookies) { set resp.http.Cookie = req.http.X-Cookies; } # Intercepte la création de session, uniquement pour la webapp call sp_session_intercept_redirect; # Récupère le Set-Cookie originel pour le renvoyer au browser afin qu'il soit conservé if (req.http.X-Set-Cookie) { if (! req.http.X-Set-Cookie ~ "^ *$") { set resp.http.Set-Cookie = req.http.X-Set-Cookie; } unset req.http.X-Set-Cookie; } # Remove some headers: PHP version unset resp.http.X-Powered-By; [...] }
  26. SP_SESSION_INTERCEPT_REDIRECT OCTO TECHNOLOGY > THERE IS A BETTER WAY sub

    sp_session_intercept_redirect { if (req.url ~ "^/session" && req.http.X-Varnish-Backend ~ "^apps" && resp.status == 302) { # Récupération de la requête originelle du client set req.url = resp.http.Location; if (resp.http.Set-Cookie) { # Extraction du nouveau cookie de session set req.http.X-Session-Cookie = regsuball(req.http.X-Session-Cookie, ";(SPPLUS_SESSION)=", "; \1="); [...] # Transfert du header Set-Cookie originel à destination du client final set req.http.X-Set-Cookie = resp.http.Set-Cookie; if (! req.http.X-Session-Cookie ~ "^ *$") { // Supprime le cookie de session existant set req.http.X-Cookies = regsuball(req.http.X-Cookies, "(^|;\s*)(_[_a-z]+| SPPLUS_SESSION)=[^;]*", ""); // Supprime le préfixe ";" si présent. set req.http.X-Cookies = regsub(req.http.X-Cookies, "^;\s*", ""); } } # Concaténation du nouveau cookie de session aux cookies existants if (req.http.X-Cookies ~ "^ *$") { set req.http.Cookie = req.http.X-Session-Cookie; } else { set req.http.Cookie = req.http.X-Cookies + "; " + req.http.X-Session-Cookie; } # Rédémarrage du workflow varnish return (restart); } }
  27. VCL_RECV [POST RESTART] OCTO TECHNOLOGY > THERE IS A BETTER

    WAY sub vcl_recv { if (req.restarts == 0) { if (req.http.X-Forwarded-For) { # set or append the client.ip to X-Forwarded-For header set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; } else { set req.http.X-Forwarded-For = client.ip; } } # Dans un fragment ESI, on récupère le cookie de la requête parente if (req.esi_level > 0) { set req.http.Cookie = req_top.http.X-Cookies; } call sp_purge; call sp_ban; call sp_healthcheck; if (! std.healthy(apps.backend())) { return(synth(503, {""})); } call sp_choose_backend; call sp_clean_request; call sp_session_generate; # return (hash); }
  28. VCL_BACKEND_* OCTO TECHNOLOGY > THERE IS A BETTER WAY sub

    vcl_backend_fetch { # Handle SPPlus webapp cookie if (bereq.http.X-Cookies) { set bereq.http.Cookie = bereq.http.X-Cookies; } } sub vcl_backend_response { if (!(beresp.status >= 200 && beresp.status <= 299)) { # Mark as "Hit-For-Pass" for the next 2 minutes set beresp.ttl = 120s; set beresp.uncacheable = true; return (deliver); } set beresp.do_esi = true; // Do ESI processing set beresp.http.X-Varnish-Backend = beresp.backend.name; [...] # Clean SPPlus webapp cookie if (bereq.http.X-Cookies) { unset beresp.http.Cookie; unset beresp.http.X-Cookies; } unset beresp.http.X-Set-Cookie; }
  29. VCL_RECV [ESI SUBCALL] OCTO TECHNOLOGY > THERE IS A BETTER

    WAY sub vcl_recv { if (req.restarts == 0) { if (req.http.X-Forwarded-For) { # set or append the client.ip to X-Forwarded-For header set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; } else { set req.http.X-Forwarded-For = client.ip; } } # Dans un fragment ESI, on récupère le cookie de la requête parente if (req.esi_level > 0) { set req.http.Cookie = req_top.http.X-Cookies; } call sp_purge; call sp_ban; call sp_healthcheck; if (! std.healthy(apps.backend())) { return(synth(503, {""})); } call sp_choose_backend; call sp_clean_request; call sp_session_generate; # return (hash); }
  30. VCL_DELIVER [FINAL RESPONSE] OCTO TECHNOLOGY > THERE IS A BETTER

    WAY sub vcl_deliver { if (req.http.X-Cookies) { set resp.http.Cookie = req.http.X-Cookies; } # Intercepte la création de session, uniquement pour la webapp call sp_session_intercept_redirect; # Récupère le Set-Cookie originel pour le renvoyer au browser afin qu'il soit conservé if (req.http.X-Set-Cookie) { if (! req.http.X-Set-Cookie ~ "^ *$") { set resp.http.Set-Cookie = req.http.X-Set-Cookie; } unset req.http.X-Set-Cookie; } # Remove some headers: PHP version unset resp.http.X-Powered-By; [...] }
  31. ESI & GESTION D’ERREURS OCTO TECHNOLOGY > THERE IS A

    BETTER WAY 41 CLIENT VARNISH BACKEND WEB GET /hello 200 /hello GET /hello BACKEND CMS SQUELETTE FRAGMENT ESI /header ERROR PAGE 500 /header ¤  BACKEND CMS FONCTIONNEL RETOURNE LE SQUELETTE ¤  BACKEND WEB KO RETOURNE UNE PAGE D’ERREUR COMME FRAGMENT ESI LA PAGE SERVIE A POUR HEADER UNE PAGE D’ERREUR… 200 /hello
  32. ESI & GESTION D’ERREURS : « PALIATIF » ¤  VÉRIFIER

    LA « BONNE SANTÉ » DU BACKEND SERVANT LES FRAGMENTS ESI ¤  SERVIR DIRECTEMENT UNE PAGE D’ERREUR EN CAS D’INDISPONIBILITÉ OCTO TECHNOLOGY > THERE IS A BETTER WAY 42 sub vcl_recv { if (req.restarts == 0) { if (req.http.X-Forwarded-For) { # set or append the client.ip to X-Forwarded-For header set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; } else { set req.http.X-Forwarded-For = client.ip; } } [...] if (! std.healthy(apps.backend())) { return(synth(503, {""})); } [...] # return (hash); }
  33. POST MORTEM VARNISH + ESI ¤  VARNISH CONFIGURATION LANGUAGE FACILEMENT

    CUSTOMISABLE (UNE FOIS S’ÊTRE APPROPRIÉ LE STATE DIAGRAM) ¤  VARNISH OK POUR MASHUP ESI D’UN SITE STATIQUE MARQUE BLANCHE ¤  ATTENTION GESTION COOKIES DANS LES FRAGMENTS ESI ¤  VARNISH OFFRE PEU DE CONTRÔLE SUR MASHUP ESI ¤  COMPLIQUER DE GÉRER ERREURS DANS FRAGMENT UN ESI ¤  VARNISH 4.1 + ESI è INTERACTION REQUÊTE PARENTE VIA REQ_TOP ¤  VARNISH NE PERMET PAS DE RÉCUPÉRER NATIVEMENT LES HEADERS MULTIPLES (CAS DU SET-COOKIE). è VMOD : https://www.varnish-cache.org/vmod/header-manipulation OCTO TECHNOLOGY > THERE IS A BETTER WAY 43
  34. VARNISH 4 FLOW HOOKS DANS LE CYCLE DE VIE DE

    LA REQUÊTE OCTO TECHNOLOGY > THERE IS A BETTER WAY 45 ¤  vcl_recv : requête client reçue ¤  vcl_hash : calcul clé de hash ¤  vcl_hit : objet trouvé en cache ¤  vcl_miss : objet non en cache ¤  vcl_backend_fetch : requête au serveur ¤  vcl_backend_response : réponse du serveur ¤  vcl_deliver : prêt à répondre au client http://varnish-cache.org/trac/wiki/VCLExampleDefault
  35. APPROCHE RETENUE VARNISH 4 BUILTIN.VCL OCTO TECHNOLOGY > THERE IS

    A BETTER WAY 46 DUPLIQUER LE COMPORTEMENT PAR DÉFAUT VARNISH DANS LE VCL CUSTOM CONSERVER LE COMPORTEMENT PAR DÉFAUT AU MAXIMUM ET COMPOSER AVEC Deux approches concernant le comportement par défaut de la configuration Varnish ¤  Code plus explicite ¤  Modifier aisément le comportement par défaut ¤  Comportement par défaut préventif peut être altéré ¤  Profite pas des potentielles évolutions du builtin.vcl ¤  Comportement par défaut à connaître, pas explicite ¤  Complexité supplémentaire (ex : cache cookies) ¤  Protégé par le comportement builtin du VCL Varnish ¤  Réduit la duplication
  36. BUILTIN.VCL - VCL_RECV OCTO TECHNOLOGY > THERE IS A BETTER

    WAY sub vcl_recv { if (req.method == "PRI") { /* We do not support SPDY or HTTP/2.0 */ return (synth(405)); } if (req.method != "GET" && req.method != "HEAD" && req.method != "PUT" && req.method != "POST" && req.method != "TRACE" && req.method != "OPTIONS" && req.method != "DELETE") { /* Non-RFC2616 or CONNECT which is weird. */ return (pipe); } if (req.method != "GET" && req.method != "HEAD") { /* We only deal with GET and HEAD by default */ return (pass); } if (req.http.Authorization || req.http.Cookie) { /* Not cacheable by default */ return (pass); } return (hash); } https://github.com/varnish/Varnish-Cache/blob/4.0/bin/varnishd/ builtin.vcl
  37. CUSTOM.VCL - VCL_RECV OCTO TECHNOLOGY > THERE IS A BETTER

    WAY sub vcl_recv { [...] call sp_clean_request_cookie; # return (hash); } DUPLIQUER LE COMPORTEMENT PAR DÉFAUT VARNISH DANS LE VCL CUSTOM CONSERVER LE COMPORTEMENT PAR DÉFAUT AU MAXIMUM ET COMPOSER AVEC sub vcl_recv { [...] [...] return (hash); } sub sp_clean_request_cookie { if (req.http.Cookie) { # Handle SPPlus webapp cookie. Store it temporarily set req.http.X-Cookies = ";" + req.http.Cookie; set req.http.X-Cookies = regsuball(req.http.X-Cookies, "; +", ";"); set req.http.X-Cookies = regsuball(req.http.X-Cookies, ";(SPREMEMBER|SPPLUS_SESSION)=", "; \1="); set req.http.X-Cookies = regsuball(req.http.X-Cookies, ";[^ ][^;]*", ""); set req.http.X-Cookies = regsuball(req.http.X-Cookies, "^[; ]+|[; ]+$", ""); # Clean empty webapp cookie if (req.http.X-Cookies ~ "^ *$") { unset req.http.X-Cookies; } # Remove all others cookies unset req.http.Cookie; } }
  38. ÉVICTION DE CACHE OCTO TECHNOLOGY > THERE IS A BETTER

    WAY 49 PURGE SUPPRIME IMMÉDIATEMENT UN OBJET DU CACHE PAR SON URL ¤  UNE URL À LA FOIS SEULEMENT ¤  CONTENU SUPPRIMÉ DE MÉMOIRE BAN AJOUTE UNE RÈGLE DE BANNISSEMENT APPLIQUÉE LORS DE LA REQUÊTE D’UNE PAGE ¤  RÈGLES SOUPLES (REGEX, HEADERS, …) ¤  RÈGLES VÉRIFIÉES AU MOMENT DE SERVIR UN CONTENU Deux approches concernant l’éviction de cache. Exposer dès le départ ces mécanismes.
  39. PURGE - VCL_RECV OCTO TECHNOLOGY > THERE IS A BETTER

    WAY sub sp_purge { # Allow purging if (req.method == "PURGE") { if (!client.ip ~ invalidators) { # invalidators is the ACL defined at the beginning # Not from an allowed IP? Then die with an error. return (synth(405, "This IP is not allowed to send PURGE requests.")); } # If you got this stage (and didn't error out above), purge the cached result return (purge); } } NE PAS OUBLIER DE GÉRER CORRECTEMENT UNE ACCESS CONTROL LIST
  40. BAN - VCL_RECV OCTO TECHNOLOGY > THERE IS A BETTER

    WAY sub sp_ban { # Allow ban if (req.method == "BAN") { if (!client.ip ~ invalidators) { # invalidators is the ACL defined at the beginning # Not from an allowed IP? Then die with an error. return (synth(405, "Method not allowed")); } if (req.http.X-Backend == "CMS") { ban("obj.http.X-Varnish-Backend ~ ^cms"); } else if (req.http.X-Backend == "WEBAPP") { if (req.http.X-Flow) { if (req.http.X-Flow == "ACTU") { ban("req.url ~ ^/resources-actu/.+ && obj.http.X-Varnish-Backend ~ ^apps"); } else if (req.http.X-Flow == "VDD") { ban("req.url ~ ^/resources-vdd/.+ && obj.http.X-Varnish-Backend ~ ^apps"); } else if (req.http.X-Flow == "LETTRESP") { ban("req.url ~ ^/resources-lettresp/.+ && obj.http.X-Varnish-Backend ~ ^apps”); } else if (req.http.X-Flow == "ITM") { ban("req.url ~ ^/annuaire/?.* && obj.http.X-Varnish-Backend ~ ^apps"); } else { return (synth(400, "Bad Request, unexisting X-Flow '" + req.http.X-Flow + "'")); } } else { ban("obj.http.X-Varnish-Backend ~ ^apps"); } } else { # HUGE BAN ! ban("req.url ~ ^/?.*$"); } return (synth(200, "Banned")); } }
  41. VARNISHTEST ¤  TEST D’INTÉGRATION ¤  LANCEMENT D’UN VÉRITABLE DAEMON VARNISH

    ¤  POSSIBILITÉ DE « MOCKER » LES BACKENDS ¤  RÉALISER DES ASSERTIONS SUR LA RÉPONSE AU CLIENT OCTO TECHNOLOGY > THERE IS A BETTER WAY 52 Bien découper votre VCL pour mutualiser au maximum la configuration pour les tests vcl 4.0; # spécifique à l'environnement include "backends.vcl"; include "acls.vcl"; # politique de cache include "rules.vcl";
  42. VARNISHTEST OCTO TECHNOLOGY > THERE IS A BETTER WAY vcl

    4.0; import directors; # load the directors sub vcl_init { new apps = directors.round_robin(); new cms = directors.round_robin(); } ACLS.VCL BACKENDS.TEST.VCL vcl 4.0; # ACL for invalidators IP acl invalidators { "localhost"; "127.0.0.1"; } sub vcl_recv { if (req.restarts == 0) { if (req.http.X-Forwarded-For) { # set or append the client.ip to X-Forwarded-For header set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip; } else { set req.http.X-Forwarded-For = client.ip; } } [...] RULES.VCL
  43. VARNISHTEST - TEST.VTC OCTO TECHNOLOGY > THERE IS A BETTER

    WAY varnishtest "Should delete trailing slash" server server_apps { rxreq txresp accept rxreq expect req.url == "/hello/world" txresp } -start varnish v1 -vcl+backend { include "{{ varnish_location }}/conf/acls.vcl"; include "{{ varnish_location }}/conf/backends.test.vcl"; include "{{ varnish_location }}/conf/rules.vcl"; sub vcl_init { apps.add_backend(server_apps); } } -start client c1 { txreq -url "/hello/world/" rxresp expect resp.status == 200 } -run
  44. VARNISHLOG ¤  USER ET ABUSER DE VARNISHLOG ¤  OFFRE UNE

    VUE DÉTAILLÉE DE TOUTES LES ÉTAPES DU VCL ¤  UTILISER VARNISHLOG QUERY LANGUAGE POUR S’Y RETROUVER PLUS FACILEMENT OCTO TECHNOLOGY > THERE IS A BETTER WAY 55 varnishlog -v –g request
  45. OCTO TECHNOLOGY > THERE IS A BETTER WAY 57 VOUS

    CROYEZ QUE LES TECHNOLOGIES CHANGENT LE MONDE ? NOUS AUSSI ! REJOIGNEZ-NOUS ! [email protected]