{"id":2262,"date":"2018-07-25T14:37:07","date_gmt":"2018-07-25T12:37:07","guid":{"rendered":"https:\/\/blog.alwaysdata.com\/?p=2262"},"modified":"2018-07-25T16:34:47","modified_gmt":"2018-07-25T14:34:47","slug":"le-cache-http","status":"publish","type":"post","link":"https:\/\/blog.alwaysdata.com\/fr\/2018\/07\/25\/le-cache-http\/","title":{"rendered":"Le cache&nbsp;HTTP"},"content":{"rendered":"<p>Deuxi\u00e8me article de notre s\u00e9rie destin\u00e9e \u00e0&nbsp;vous pr\u00e9senter les nouveaut\u00e9s de notre <em>reverse-proxy<\/em> HTTP. Apr\u00e8s le <a href=\"https:\/\/blog.alwaysdata.com\/fr\/2018\/07\/24\/le-pare-feu-applicatif-web-waf\/\">pare-feu applicatif<\/a>, nous vous pr\u00e9sentons le cache HTTP frontal que nous avons int\u00e9gr\u00e9 \u00e0&nbsp;notre infrastructure.<\/p>\n<div class=\"embed-media__giphy\" style=\"width:65%;padding-bottom:27%;\"><img decoding=\"async\" alt=\"punch it star trek GIF @Giphy\" src=\"https:\/\/media.giphy.com\/media\/4iRDkqvIH5U9G\/giphy-downsized-large.gif\"><\/div>\n<h2>Un cache HTTP, qu\u2019est-ce que&nbsp;c\u2019est&nbsp;?<\/h2>\n<h3>Un graphique vaut mieux qu\u2019un long discours<\/h3>\n<p>Nous avons test\u00e9 les performances de notre cache fra\u00eechement int\u00e9gr\u00e9 \u00e0&nbsp;notre proxy sur notre blog, servi par une application WordPress. Le r\u00e9sultat obtenu nous laisse \u00e0&nbsp;penser que cette fonctionnalit\u00e9 va vous plaire.<\/p>\n<p><\/p><canvas id=\"chart\" height=\"100\" class=\"aligncenter embed-media__ad__medium\"><\/canvas>\n<p>Le nombre de requ\u00eates servies par seconde augmente consid\u00e9rablement lorsqu\u2019on active notre cache, passant de 15 req\/s \u00e0&nbsp;2604 req\/s, soit <strong>173<\/strong> fois plus de requ\u00eates servies sur une m\u00eame dur\u00e9e. Le temps mis pour obtenir la r\u00e9ponse \u00e0&nbsp;une requ\u00eate baisse d\u2019autant, passant de 63.65ms \u00e0&nbsp;0.38ms en moyenne. Int\u00e9ressant, et tr\u00e8s simple \u00e0&nbsp;activer&nbsp;!<\/p>\n<p>Nous avons r\u00e9alis\u00e9 ce benchmark avec <em>ApacheBench<\/em> en faisant des requ\u00eates vers la page d\u2019accueil de ce blog.  Nous avons ex\u00e9cut\u00e9 chaque tir<span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_2262_1('footnote_plugin_reference_2262_1_1');\" onkeypress=\"footnote_moveToReference_2262_1('footnote_plugin_reference_2262_1_1');\"><sup id=\"footnote_plugin_tooltip_2262_1_1\" class=\"footnote_plugin_tooltip_text\">1)<\/sup><\/a><span id=\"footnote_plugin_tooltip_text_2262_1_1\" class=\"footnote_tooltip\"><\/span><\/span> quatre fois pour chaque configuration, avec et sans cache, avant de faire la moyenne des r\u00e9sultats obtenus. Ce blog est h\u00e9berg\u00e9 sur un serveur d\u00e9di\u00e9, les diff\u00e9rences de performances mesur\u00e9es sur un serveur mutualis\u00e9 seront du m\u00eame ordre. Vous pouvez d\u2019ailleurs faire vos propres tests en vous connectant en SSH \u00e0&nbsp;votre serveur, et en ex\u00e9cutant la commande <code>ab<\/code> avec les m\u00eames options sur une page de votre&nbsp;site.<\/p>\n<h3>Fonctionnement d\u2019un&nbsp;cache<\/h3>\n<p>Le cache d\u00e9signe un syst\u00e8me de stockage temporaire de donn\u00e9es dans le but d\u2019en acc\u00e9l\u00e9rer le traitement ult\u00e9rieur. Un cache HTTP s\u2019occupe de stocker temporairement des documents web comme les pages HTML, les documents CSS, les images, etc. Ce m\u00e9canisme est principalement utilis\u00e9 pour diminuer la latence induite par le serveur lorsqu\u2019il doit servir une page et\/ou r\u00e9duire sa charge de travail.<\/p>\n<p>Lorsqu\u2019un client demande une page \u00e0&nbsp;un serveur web, ce dernier va g\u00e9n\u00e9rer une page et l\u2019envoyer sur le r\u00e9seau. Le cache intercepte la r\u00e9ponse \u00e0&nbsp;ce moment, et la stocke dans sa m\u00e9moire locale avant de la servir au client.<\/p>\n<figure class=\"embed-media__ad__medium\">\n    <img decoding=\"async\" src=\"https:\/\/blog.alwaysdata.com\/wp-content\/uploads\/2018\/07\/http_cache_part_1.fr_.png\" alt=\"Sch\u00e9ma de mise en cache d'une resource web\" class=\"aligncenter size-full wp-image-2429\"><figcaption>Mis en cache d\u2019une ressource lors de sa requ\u00eate <small>(ic\u00f4nes&nbsp;: The Noun Project)<\/small><\/figcaption><\/figure>\n<p>Lorsqu\u2019une requ\u00eate pour la m\u00eame page est \u00e9mise par un client, elle sera directement servie par le cache qui d\u00e9tient d\u00e9sormais une copie de la ressource demand\u00e9e. Le serveur web ne sera plus interrog\u00e9.<\/p>\n<figure class=\"embed-media__ad__medium\">\n    <img decoding=\"async\" width=\"792\" height=\"449\" src=\"https:\/\/blog.alwaysdata.com\/wp-content\/uploads\/2018\/07\/http_cache_part_2.fr_.png\" alt=\"Sch\u00e9ma d'une resource web servie par un cache\" class=\"aligncenter size-full wp-image-2431\" srcset=\"https:\/\/blog.alwaysdata.com\/wp-content\/uploads\/2018\/07\/http_cache_part_2.fr_.png 792w, https:\/\/blog.alwaysdata.com\/wp-content\/uploads\/2018\/07\/http_cache_part_2.fr_-300x170.png 300w, https:\/\/blog.alwaysdata.com\/wp-content\/uploads\/2018\/07\/http_cache_part_2.fr_-768x435.png 768w\" sizes=\"(max-width: 792px) 100vw, 792px\"><figcaption>Restitution d\u2019une ressource pr\u00e9c\u00e9demment mise en cache <small>(ic\u00f4nes&nbsp;: The Noun Project)<\/small><\/figcaption><\/figure>\n<h2>Utiliser le cache chez alwaysdata<\/h2>\n<p>Vous pouvez activer le cache frontal pour chaque site individuellement en vous rendant simplement dans <em>Sites  \u2192 Modification \u2192 Cache<\/em>, puis en cochant la case <em>Activer le cache<\/em>.<\/p>\n<p><img decoding=\"async\" width=\"1000\" height=\"595\" src=\"https:\/\/blog.alwaysdata.com\/wp-content\/uploads\/2018\/07\/screenshot-ad-ui-cache.fr_.png\" alt=\"Capture d'\u00e9cran de l'interface d'administration pourla configuration du cache HTTP par site\" class=\"aligncenter size-full wp-image-2493 embed-media__ad__medium\" srcset=\"https:\/\/blog.alwaysdata.com\/wp-content\/uploads\/2018\/07\/screenshot-ad-ui-cache.fr_.png 1000w, https:\/\/blog.alwaysdata.com\/wp-content\/uploads\/2018\/07\/screenshot-ad-ui-cache.fr_-300x179.png 300w, https:\/\/blog.alwaysdata.com\/wp-content\/uploads\/2018\/07\/screenshot-ad-ui-cache.fr_-768x457.png 768w\" sizes=\"(max-width: 1000px) 100vw, 1000px\"><\/p>\n<p>Il vous faudra r\u00e9gler le <a href=\"https:\/\/fr.wikipedia.org\/wiki\/Time_to_Live\">TTL<\/a> pour les pages issues de ce site. Le TTL d\u00e9finit la dur\u00e9e pendant laquelle le cache peut servir une page. Sa valeur doit \u00eatre s\u00e9lectionn\u00e9e avec soin. S\u2019il est bon de choisir un TTL \u00e9lev\u00e9 pour un site dont le contenu n\u2019est pas souvent mis \u00e0&nbsp;jour&nbsp;; il sera en revanche judicieux d\u2019abaisser cette valeur dans le cas d\u2019un site dont le contenu change tr\u00e8s r\u00e9guli\u00e8rement, comme un site de news. Dans ce dernier cas, si le TTL reste \u00e9lev\u00e9, le visiteur peut se retrouver avec une version p\u00e9rim\u00e9e de la page demand\u00e9e.<\/p>\n<p>Prenons l\u2019exemple de ce blog. Nous souhaitons nous assurer qu\u2019un visiteur se retrouve avec une version relativement fra\u00eeche de la page d\u2019accueil. Lorsque nous ajoutons un article, la page d\u2019accueil cach\u00e9e auparavant sera p\u00e9rim\u00e9e. Nous allons donc pr\u00e9f\u00e9rer une valeur de TTL comprise entre 5&nbsp;et 10 secondes afin de b\u00e9n\u00e9ficier des hausses de performances sans risquer de servir la page cach\u00e9e pendant une dur\u00e9e trop longue.<\/p>\n<p class=\"inset\" data-title=\"Note\">Cette fonctionnalit\u00e9 est consid\u00e9r\u00e9e comme en b\u00eata test et susceptible d\u2019\u00e9voluer encore.<\/p>\n<p class=\"inset warning\" data-title=\"Important\">Cette fonctionnalit\u00e9 est d\u00e9pendante de la capacit\u00e9 de votre application \u00e0&nbsp;autoriser les pages g\u00e9n\u00e9r\u00e9es \u00e0&nbsp;\u00eatre cach\u00e9es. Si cette derni\u00e8re ne l\u2019autorise pas explicitement, il y&nbsp;a un risque que notre proxy ne puisse pas cacher les ressources qui sont servies par&nbsp;elle.<\/p>\n<h2>L\u2019impl\u00e9mentation<\/h2>\n<p>Nous avons choisi d\u2019\u00e9crire en Python<span class=\"footnote_referrer\"><a role=\"button\" tabindex=\"0\" onclick=\"footnote_moveToReference_2262_1('footnote_plugin_reference_2262_1_2');\" onkeypress=\"footnote_moveToReference_2262_1('footnote_plugin_reference_2262_1_2');\"><sup id=\"footnote_plugin_tooltip_2262_1_2\" class=\"footnote_plugin_tooltip_text\">2)<\/sup><\/a><span id=\"footnote_plugin_tooltip_text_2262_1_2\" class=\"footnote_tooltip\"><\/span><\/span> un module int\u00e9grant les sp\u00e9cifications du standard expos\u00e9es dans la <a href=\"https:\/\/tools.ietf.org\/html\/rfc7234\">RFC 7234<\/a>. Le stockage des ressources cach\u00e9es, quant \u00e0&nbsp;lui, est confi\u00e9 \u00e0&nbsp;un serveur <a href=\"https:\/\/redis.io\/\">Redis<\/a> local permettant l\u2019optimisation de la m\u00e9moire utilis\u00e9e avec tr\u00e8s peu d\u2019efforts.<\/p>\n<p>En plus des sp\u00e9cifications li\u00e9es \u00e0&nbsp;la RFC, nous avons impl\u00e9ment\u00e9 le verbe HTTP <em>PURGE<\/em>. Cette m\u00e9thode offre la possibilit\u00e9 de supprimer une entr\u00e9e dans le cache par le client juste en l\u2019appelant sur son URL. Ceci peut \u00eatre utile lorsque vous cherchez \u00e0&nbsp;forcer le rafra\u00eechissement d\u2019une page mise en&nbsp;cache.<\/p>\n<hr>\n<p>Apr\u00e8s la performance, la journalisation&nbsp;! Dans le prochain et dernier billet de cette s\u00e9rie, nous vous pr\u00e9senterons notre syst\u00e8me de <a href=\"https:\/\/blog.alwaysdata.com\/fr\/2018\/07\/26\/les-logs-personnalises\/\">personnalisation des lignes de logs<\/a> g\u00e9n\u00e9r\u00e9es par vos serveurs web. Vous allez d\u00e9sormais pouvoir les formater selon vos besoins.<\/p>\n<div class=\"speaker-mute footnotes_reference_container\"> <div class=\"footnote_container_prepare\"><p><span role=\"button\" tabindex=\"0\" class=\"footnote_reference_container_label pointer\" onclick=\"footnote_expand_collapse_reference_container_2262_1();\">Notes<\/span><span role=\"button\" tabindex=\"0\" class=\"footnote_reference_container_collapse_button\" style=\"display: none;\" onclick=\"footnote_expand_collapse_reference_container_2262_1();\">[<a id=\"footnote_reference_container_collapse_button_2262_1\">+<\/a>]<\/span><\/p><\/div> <div id=\"footnote_references_container_2262_1\" style><table class=\"footnotes_table footnote-reference-container\"><caption class=\"accessibility\">Notes<\/caption> <tbody> \n\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\" onclick=\"footnote_moveToAnchor_2262_1('footnote_plugin_tooltip_2262_1_1');\"><a id=\"footnote_plugin_reference_2262_1_1\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">\u2191<\/span>1<\/a><\/th> <td class=\"footnote_plugin_text\"><code>ab -c 10 -t 60 <span class=\"footnote_url_wrap\">http:\/\/blog.alwaysdata.com\/<\/span><\/code><\/td><\/tr>\n\n<tr class=\"footnotes_plugin_reference_row\"> <th scope=\"row\" class=\"footnote_plugin_index_combi pointer\" onclick=\"footnote_moveToAnchor_2262_1('footnote_plugin_tooltip_2262_1_2');\"><a id=\"footnote_plugin_reference_2262_1_2\" class=\"footnote_backlink\"><span class=\"footnote_index_arrow\">\u2191<\/span>2<\/a><\/th> <td class=\"footnote_plugin_text\">parce qu\u2019on aime bien Python chez alwaysdata<\/td><\/tr>\n\n <\/tbody> <\/table> <\/div><\/div><script type=\"text\/javascript\"> function footnote_expand_reference_container_2262_1() { jQuery('#footnote_references_container_2262_1').show(); jQuery('#footnote_reference_container_collapse_button_2262_1').text('\u2212'); } function footnote_collapse_reference_container_2262_1() { jQuery('#footnote_references_container_2262_1').hide(); jQuery('#footnote_reference_container_collapse_button_2262_1').text('+'); } function footnote_expand_collapse_reference_container_2262_1() { if (jQuery('#footnote_references_container_2262_1').is(':hidden')) { footnote_expand_reference_container_2262_1(); } else { footnote_collapse_reference_container_2262_1(); } } function footnote_moveToReference_2262_1(p_str_TargetID) { footnote_expand_reference_container_2262_1(); var l_obj_Target = jQuery('#' + p_str_TargetID); if (l_obj_Target.length) { jQuery( 'html, body' ).delay( 0 ); jQuery('html, body').animate({ scrollTop: l_obj_Target.offset().top - window.innerHeight * 0.2 }, 380); } } function footnote_moveToAnchor_2262_1(p_str_TargetID) { footnote_expand_reference_container_2262_1(); var l_obj_Target = jQuery('#' + p_str_TargetID); if (l_obj_Target.length) { jQuery( 'html, body' ).delay( 0 ); jQuery('html, body').animate({ scrollTop: l_obj_Target.offset().top - window.innerHeight * 0.2 }, 380); } }<\/script>","protected":false},"excerpt":{"rendered":"<p>Pour servir vos pages pr\u00e8s de 200 fois plus vite, nous mettons \u00e0&nbsp;votre disposition un Cache HTTP conforme \u00e0&nbsp;la RFC&nbsp;7234&nbsp;!&nbsp;<\/p>\n","protected":false},"author":10,"featured_media":2424,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"wp_typography_post_enhancements_disabled":false,"footnotes":""},"categories":[],"tags":[242,229,225,243,244],"class_list":["post-2262","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-core-fr","tag-fonctionnalites-fr","tag-mises-a-jour-fr","tag-performance-fr","tag-proxy-fr"],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/posts\/2262","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/users\/10"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/comments?post=2262"}],"version-history":[{"count":0,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/posts\/2262\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/media\/2424"}],"wp:attachment":[{"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/media?parent=2262"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/categories?post=2262"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.alwaysdata.com\/fr\/wp-json\/wp\/v2\/tags?post=2262"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}